Consider a component in React which has its own state and also uses some shared state (shared states are stored within a Store).
Here's a sample component for better understanding the question:
var ControllerView = React.createClass({
getInitialState: function() {
return {privateState: 1, sharedState: -1};
},
componentDidMount: function() {
Store.addChangeListener(this._onChange);
},
componentWillUnmount: function() {
Store.removeChangeListener(this._onChange);
},
_onChange: function() {
this.setState({
privateState: this.state.privateState,
sharedState: Store.getSharedState()
});
}
stepForward: function() {
this.setState({
privateState: this.state.privateState + 1,
sharedState: this.state.sharedState
});
Action.decrease();
},
render: function() {
return (
<div>
<button onClick={this.stepForward}>Go forth with private and shared state</button>
<div>Private State: {this.state.privateState}</div>
<div>Shared State: {this.state.sharedState}</div>
</div>
);
}
});
As you can see in the given code, there's a button which pressing it will result in changing both private state and shared state. A private state can simply be updated by calling the setState
method. But following the Flux architecture, updating a store should go through actions
. That's why there's a Action.decrease();
.
Just a recap of what will happen when an action is called;
_onChange
is called.So when the button is pressed, the component's state will update twice, once to update the private state and the second time when _onChange
is called to update the shared state. These two setState
calls happen one after the other in one thread.
What I experienced is that in such cases only the last setState
will apply and the previous ones are discarded. My question is how to overcome this problem?
答案 0 :(得分:0)
调用setState时,应该只包含实际更新的属性 - 状态中的其他属性将保持不变。您正在看到这样一个事实:当调用setState时,this.state不会立即更新,而只会在实际的反应渲染开始后(紧接在componentWillUpdate()之后和render()之前)。因此,当您调用第二个setState时,您将使用旧值替换privateState的新值(它仍保留在this.state中,直到渲染发生)。因此,您的代码应如下所示:
_onChange: function() {
this.setState({
sharedState: Store.getSharedState()
});
}
stepForward: function() {
this.setState({
privateState: this.state.privateState + 1,
});
Action.decrease();
}