我已阅读有关 setState 的ReactJS文档。具体来说,这一行:
不要直接改变this.state,因为之后调用setState()可能会替换你所做的突变。把this.state看作是不可变的。
但是在我的代码中,我做了这样的事情:
var x = this.state.x;
x.y.z.push("foo"); // z is a list
this.setState({x:x});
此代码似乎正常工作并正确更新状态。但根据文件,我违反了规则。这种方法有什么问题?有性能问题吗?比赛条件?我会被Facebook开发团队骂?理想情况下,我想避免不可变性助手和所有其他疯狂,并保持简单。
答案 0 :(得分:5)
通过直接操纵状态,你正在规避React的状态管理,这对React范式起作用。 React的setState
最显着的好处是它会立即触发重新渲染,将DOM中的DOM更改与shadow DOM合并到文档DOM中。因此,您捕获某个处理程序中所需的所有状态更改,然后在文字对象中构建所需的状态更改,然后将其传递给setState
。这不是你上面的例子。
因此,虽然您提供的技术上的代码示例违反了此规则,但由于您在通过对状态对象属性的引用进行变更后直接调用setState
,因此您的更改会立即通过反应的国家管理。所以,一切都会按预期工作。这个想法是你不想养成以这种方式对状态进行许多更改的习惯,最好在新的文字对象或数组中捕获你想要的状态,然后将其设置为通过调用setState
状态一次(即没有先前的状态突变),这将触发单个重新渲染。
setState
,然后在某个稍后的点或其他代码中,调用setState
,然后想知道为什么他们的渲染不会产生他们期望的结果。由于setState
在已知的托管状态和作为参数传递给setState
的文字对象之间执行了一个对象 merge ,因此结果可能不会是如果您之前曾直接操纵州,那么您会期待什么。
答案 1 :(得分:3)
原因是您错过了与this.setState
相关联的回调,他们声称您可以通过直接指定对象来覆盖数据。
另外,经常在OOP中(我不知道JS有多少星......)你将使用getter和setter方法而不是直接操作对象。在此示例中,通过this.state.prop1 = "xyz";
我从来没有反应覆盖我直接设置的状态属性。以这种方式编码的诱惑可能是写入状态而无需重新渲染。但是,如果你这样做,你可能会考虑不要把它们放在州里。
如果重新呈现效果是问题结帐https://facebook.github.io/react/docs/component-specs.html#updating-shouldcomponentupdate
答案 2 :(得分:-1)
主要原因是shouldComponentUpdate无法正常工作。