Thursday, March 29, 2018

[React.js] Incorrect and correct methods to update component state

Suppose there is a component with function named countViewtimes, it would be ran for total 5 times with viewtimes 133,112,13,29 and 56. And default value of state state named "viewtimes" is 0. My aim is to sum up all viewtimes. Please guess what is the final result of the state named "viewtimes":

Version 1: use = sign to assign value

countViewtimes: function(viewtimes){
    this.state.viewtimes = this.state.viewtimes+viewtimes;
}
Final value of  this.state.viewtimes : 0
 
Since React can't listen to your updated state in this way. Your component is not able to be rendered. So nothing changes and state of viewtimes is still 0, the default value.

Version 2: using setState()

countViewtimes: function(viewtimes){
    this.setState({viewtimes:this.state.viewtimes+viewtimes});
},
final value of  this.state.viewtimes : 56

setState() enqueues changes to the component state and tells React that this component and its children need to be re-rendered with the updated state.
However, using setState() with this method is not asychronous and might cause problem without sync state data. Final value of this.state.viewtimes is 56 but the result is not expected (expected result : 133+112+13+29+56 = 343).

Version 3: use setState() with updater function

countViewtimes: function(viewtimes){
    this.setState((prevState, props) => {
        return { viewtimes: prevState.viewtimes + viewtimes }
    });
}, 
or
countViewtimes: function(viewtimes){
    this.setState((prevState) => {
        return { viewtimes: prevState.viewtimes + viewtimes }
    });
}, 
final value of  this.state.viewtimes :343
This is suggested way : taking a callback function with a new object based on the input from prevState and props(optional) as argument of setState(), rather than updating the state directly.

setState() runs asynchronously and does not always update the component immediately. In this case updates of state viewtimes are base on previous state, we need to use updater updates state which is based on prevState and props. Here is the updater signature:
(prevState, props) => stateChange

Reference

https://reactjs.org/docs/react-component.html#setstate
http://lucybain.com/blog/2016/react-state-vs-pros/

No comments :

Post a Comment