我知道,React教程和文档毫无疑问地警告说,状态不应该直接变异,所有事情都应该通过setState
。
我想了解一下,为什么我不能直接更改状态,然后(在同一函数中)调用this.setState({})
仅触发render
。
例如:以下代码似乎正常工作:
const React = require('react');
const App = React.createClass({
getInitialState: function() {
return {
some: {
rather: {
deeply: {
embedded: {
stuff: 1
}}}}};
},
updateCounter: function () {
this.state.some.rather.deeply.embedded.stuff++;
this.setState({}); // just to trigger the render ...
},
render: function() {
return (
<div>
Counter value: {this.state.some.rather.deeply.embedded.stuff}
<br></br>
<button onClick={this.updateCounter}>inc</button>
</div>
);
}
});
export default App;
I am all for following conventions but I would like to enhance my further understanding of how ReactJS actually works and what can go wrong or is it sub-optimal with the above code.
The notes under the this.setState
documentation basically identify two gotchas:
- That if you mutate state directly and then subsequently call
this.setState
this may replace (overwrite?) the mutation you made. I don't see how this can happen in the above code. - That
setState
may mutatethis.state
effectively in an asynchronous / deferred way and so when accessingthis.state
right after callingthis.setState
you are not guaranteed to access the final mutated state. I get that, by this is not an issue ifthis.setState
is the last call of the update function.
React文档
setState
对此有这样的说法:基本上,如果
this.state
直接进行修改,则会造成一种情况,即这些修改可能会被覆盖。与您的扩展问题1)和2)有关,
setState()
不是立即的。它根据其正在进行的状态对状态转换进行排队,该状态转换可能不包括对的直接更改this.state
。由于已排队而不是立即应用,因此完全有可能在两者之间进行某些修改,以使您的直接更改被覆盖。如果没有别的,您可能会觉得更好,只是考虑将不直接修改
this.state
视为良好做法。您可能个人知道您的代码与React交互时不会发生这些覆盖或其他问题,但是您正在创建一种情况,其他开发人员或将来的更新可能突然发现自己遇到奇怪或微妙的问题。