I have a function that changes the screen and sets the state at the same time that works given below (initial state of weapon is null):
var { navigate } = this.props.navigation;
clickM16 = () => {
this.setState({
weapon: "M16"
});
navigate("Second", {weapon: this.state.weapon});
}
And I am calling this on my second screen via {this.props.navigation.state.weapon}, but the state doesn't seem to update to M16 until I go back and click the button again.
I have console logged both above and below the setState function and on the first click it always gives me null but M16 when I go back and click it again.
Can I not run setState at the same time as navigating between screens? If I can what am I doing wrong.
TLDR: I'm trying to set state and change page in same function so I can then display the new state on the new page as text. The state change doesn't happen until the second click of the button.
I have a function that changes the screen and sets the state at the same time that works given below (initial state of weapon is null):
var { navigate } = this.props.navigation;
clickM16 = () => {
this.setState({
weapon: "M16"
});
navigate("Second", {weapon: this.state.weapon});
}
And I am calling this on my second screen via {this.props.navigation.state.weapon}, but the state doesn't seem to update to M16 until I go back and click the button again.
I have console logged both above and below the setState function and on the first click it always gives me null but M16 when I go back and click it again.
Can I not run setState at the same time as navigating between screens? If I can what am I doing wrong.
TLDR: I'm trying to set state and change page in same function so I can then display the new state on the new page as text. The state change doesn't happen until the second click of the button.
Share Improve this question edited Apr 14, 2018 at 8:33 Peter Mortensen 31.6k22 gold badges110 silver badges133 bronze badges asked Apr 6, 2018 at 1:11 user9069254user9069254 1632 silver badges12 bronze badges4 Answers
Reset to default 4Try putting a small timeout for the navigate. The state change may not be plete when you hit the navigate instruction
var { navigate } = this.props.navigation;
clickM16 = () => {
this.setState({
weapon: "M16"
});
setTimeout(() => navigate("Second", {weapon: this.state.weapon}),20);
}
State
is supposed to be used as a helper to handle a small amount of data inside your ponent. The state life cycle ends as the ponent it belongs pletely unmount. Also, note that setState
is an asynchronous function, so you must not rely on React to handle sync situations for you. Updating your state will also make your ponent rerender, so you should use it carefully to avoid loss memory unnecessarily.
If you just want to pass data from a ponent to another, in this case using navigation props is enough, like this navigate("Second", {weapon: 'M16'});
. You don't need to update your state to then be able to pass this data further. In fact, it makes no sense to update your state before navigation, since the current state itself will be lost in the next screen.
If you need to share the exact same state prop between more ponents, which doesn't seem to be the case, maybe you should consider using another approach, like Redux (https://redux.js/).
I remend you to read the official docs for more detailed info:
https://reactjs/docs/react-ponent.html#state
https://reactjs/docs/state-and-lifecycle.html
Hope it helps
Edit:
Based on the information you provided below, if weapon
will be an array, for example, and you need to push a new value to it before navigation, you should not use setState
, try this instead:
const { navigate } = this.props.navigation;
clickM16 = () => {
const { weapon } = this.state;
weapon.push('M16');
navigate("Second", { weapon });
}
Hope it helps
I will give another suggestion:
var { navigate } = this.props.navigation;
clickM16 = () => {
this.setState({
weapon: "M16"
});
let sendPara = this.state.weapon
navigate("Second", {weapon: sendPara});
}
Recive parameter in respective ponent.
catName={this.props.navigation.state.params.sendPara}
I hope this may help you.
I will leave here one little trick I use to go around this:
Set the state with a function and assign it to 'onMouseDown' Then leave the navigation for a separate function and assign it to 'onClick' The state will be updated at the moment you click