Reputation: 1974
I want to set state a nested object and I tried this answer, but I don't know everytime I setState
following the answer, the state still not set
Here's my code I've tried:
// declare the state
constructor(props){
super(props);
this.state = {
bius: {name:'bius', time:0, status:false},
}
}
// Function to setstate
_timer(name){
// this.setState({[name]: !this.state.name})
var upd = {...this.state[name]}
upd.status = !upd.status
console.log(upd.status)
console.log(this.state.bius)
this.setState({upd})
console.log("setstate upd")
console.log(upd)
console.log(this.state.bius)
}
// here I call the function to set state
<TouchableOpacity onPress={()=>{this._timer('bius')}}>
<Text style={[global.global.SubHeaderText, {color:'white'}]}>Start</Text>
</TouchableOpacity>
and here is output of log :
I/ReactNativeJS(6694): true
I/ReactNativeJS(6694): { name: 'bius', time: 0, status: false }
I/ReactNativeJS(6694): setstate upd
I/ReactNativeJS(6694): { name: 'bius', time: 0, status: true }
I/ReactNativeJS(6694): { name: 'bius', time: 0, status: false }
I don't know why the upd.status
already true
, but the this.state.bius.status
still false
?
why this.state.bius.status
not set to true
?
Upvotes: 0
Views: 207
Reputation: 604
this.setState() updates the state asynchronously. That is why you do not see in console log. To get the log correctly add a console.log in render function as below .
export default class app extends Component {
constructor(props) {
super(props);
this.state = {
bius: { name: 'bius', time: 0, status: false },
}
}
// Function to setstate
_timer(name) {
var upd = { ...this.state[name] }
upd.status = !upd.status
this.setState({ bius: upd })
}
render() {
console.log("MYLOG", this.state.bius)
return (
<TouchableOpacity style={{ margin: 100 }} onPress={() => { this._timer('bius') }}>
<Text >Start</Text>
</TouchableOpacity>
)
}
}
Upvotes: 1
Reputation: 29
setState is async function. So, if you want to print your state, you should console.log() on call back. For example:
this.setState({bius: {name:'example'}},()=>{console.log(this.state)})
Upvotes: 1
Reputation: 80
You need to bind the event. Read this react documentation
You also need to use the spread operator here and only change the key you wish too
this._timer.bind(this,'bius');
//..
this.setState(prevState => ({
bius: {
...prevState.bius,
status: !prevState.bius.status
}));
Also you upd.status = !upd.status;
won't work as the state has not changed. You need to call setState there too. And another thing as mentioned in a comment on your question. You should use arrow functions if you are not going to bind the event handler.
Upvotes: 2
Reputation: 3359
I think you have to mistake i this.setState({upd})
You can do another way this.setState({bius:upd})
Try this one let me know whats happened.
Upvotes: 0