简体   繁体   中英

Can't pass state to another component [react-native]

I am trying to send request to api, and save one of the parameters I get from there inside my state, and then send it to another component to be used.

getCode function to send request, class method

getCode(text, psw) {
fetch('someurl', {
  method: 'POST',
  headers: {
    Accept: 'application/json',
    'Content-Type': 'application/json'
  },
    body: JSON.stringify({"telephone": text, "password": psw})
  })
  .then(response => response.json())
  .then(response => {
    //console.log(this.state.text) console.log(this.state.uid)

    this.setState({uid: response["data"]["id"]
    })
    console.log(this.state.uid)
    // this.setState({uid: response["data"]["telephone"]})
    // console.log(this.state.uid);
  })
  }

Button which runs getcode function and navigates to another screen/component where I want to send my state

<Button
      title="do it"
      onPress=
      {() => {this.props.navigation.navigate('SecondPage', {uid: this.state.uid}), this.getCode(this.state.text, this.state.password)} }/>
  </View>

Here is my constructor and state of sender component

constructor(props) {
super(props);
this.state = {
  text: '',
  password: '',
  password2: '',
  uid: ''
}
}

Here is constructor and state of second component

constructor(props) {
    super(props);
    this.state = {
      value: "",
      focused: false,
      text: "",
      u_id: this.props.navigation.state.params.uid,
    };
  }

So the question is how do I send state to another component? tried couple tutorial but not working for me. And should I use props instead of state, since they are public? Please feel free to give advices on logic and code overall

Looking at the code in your button, it seems strange that you are calling the function to get the code after you have navigated to the next screen.

<Button
  title="do it"
  onPress=
    {() => {
      this.props.navigation.navigate('SecondPage', { uid: this.state.uid });
      this.getCode(this.state.text, this.state.password);
    }}/>

Calling the function that gets your code after you navigate means that your uid value will not have updated.

If you want to get the code then pass the code to the next screen I would imagine that you should be doing something like this:

getCode = (text, psw) => {
  fetch('someurl', {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ 'telephone': text, 'password': psw })
  })
    .then(response => response.json())
    .then(response => {
      let uid = response['data']['id'];
      // this is the correct way to check a value after you have set it to state
      this.setState({ uid }, () => console.log(this.state.uid));

      // now that we have got the code we should navigate to the next screen
      // passing the uid as a parameter
      this.props.navigation.navigate('SecondPage', { uid });
    });
}

I would then change the code in the onPress of your button to

<Button
  title="do it"
  onPress=
    {() => {
      this.getCode(this.state.text, this.state.password);
    }}/>

Then you should be able to access the value in the next screen by using this.props.navigation.state.params.uid

You cannot send state from one component to another, but they can share one instance of state if you pass the state to both of them through props. If you want you can dive in Redux - State management library, which provides single source of state for all components, or the quick solution is that if your components share the same parent than you can lift your state there.

Component A is Parent its state is

this.state = {
  uuid: null
}

you create a method which sets this uuid prop for you ie

setUuid = (uuid) => {this.setState({ uuid })}

You have to pass it to your fetch function through props and call it there in then callback like this

    getCode(text, psw) {
fetch('someurl', {
  method: 'POST',
  headers: {
    Accept: 'application/json',
    'Content-Type': 'application/json'
  },
    body: JSON.stringify({"telephone": text, "password": psw})
  })
  .then(response => response.json())
  .then(response => {
    this.props.setUuid(response["data"]["id"])
  })
  }

This will update the state of the parent and now you can pass this uuid prop from parent to the component where you are using it in your case it is

<Button
  title="do it"
  onPress=
  {() => {this.props.navigation.navigate('SecondPage', {uuid: this.props.uuid}), this.getCode(this.state.text, this.state.password)} }/>

Also please notice that in onPress prop you reference uuid like uid, in the above code snippet I fixed that for you.

Why are you navigating to another screen while your fetch is not complete yet? You should either wait for the response to complete, set state, and after state has been set navigate to the next screen, or just pass the required data (telephone and password) to next screen as props and let it call the API itself.

Also you have a bug, this.props.text should be this.state.text

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM