React中setState的注意点
setState注意点
setState() 不会立刻改变 this.state ,而是创建一个即将处理的 state 转变。在调用该方法之后访问 this.state 可能会返回现有的值。
1. setState不保证同步
一般是异步的,在某些情况下也是可以同步更新的。同步更新
对 setState 的调用没有任何同步性的保证,并且调用可能会为了性能收益批量执行。
2. setState会造成不必要的渲染
造成不必要渲染的原因:
新的
state其实和之前的是一样的。这个问题通常可以通过shouldComponentUpdate来解决。也可以用pure render或者其他的依赖库解决这个问题。通常发生改变的
state是和渲染有关的,但是也有例外。比如,有些数据是根据某些状态来显示的。有些
state和渲染一点关系都没有。有一些state可能是和事件、timer ID有关的。
setState() 将总是触发一次重绘,除非在 shouldComponentUpdate() 中实现了条件渲染逻辑。如果可变对象被使用了,但又不能在 shouldComponentUpdate() 中实现这种逻辑,仅在新 state 和之前的 state 存在差异的时候调用 setState() 可以避免不必要的重新渲染。
3.setState并不能很有效的管理所有的组件状态
根据原因3:有些
state和渲染一点关系都没有。有一些state可能是和事件、timer ID有关的。
并不是所有的组件状态都应该用 setState 来进行保存和更新的。复杂的组件可能会有各种各样的状态需要管理。用 setState 来管理这些状态不但会造成很多不需要的重新渲染,也会造成相关的生命周期钩子一直被调用,从而造成很多奇怪的问题。
如何在setState后直接获取修改后的值
①传入对应的参数,不通过this.state获取
②使用回调函数
setState 方法接收一个 function 作为回调函数。这个回调函数会在 setState 完成以后直接调用,这样就可以获取最新的 state 。对于之前的例子,就可以这样:
onSelect(value) {
this.setState({
selection: value
}, this.fireOnSelect)
}
fireOnSelect() {
if (typeof this.props.onSelect === "function")
this.props.onSelect(this.state.selection) /* not what you expected..*/
}
③使用setTimeout
在 setState 使用 setTimeout 来让 setState 先完成以后再执行里面内容。这样子:
onSelect(value) {
this.setState({
selection: value
});
setTimeout(this.fireOnSelect, 0);
}
fireOnSelect() {
if (typeof this.props.onSelect === "function")
this.props.onSelect(this.state.selection) /* not what you expected..*/
}
总结
和渲染无关的状态尽量不要放在 state 中来管理
通常 state 中只来管理和渲染有关的状态 ,从而保证 setState 改变的状态都是和渲染有关的状态。这样子就可以避免不必要的重复渲染。其他和渲染无关的状态,可以直接以属性的形式保存在组件中,在需要的时候调用和改变,不会造成渲染。
避免不必要的修改,当 state 的值没有发生改变的时候,尽量不要使用 setState 。虽然 shouldComponentUpdate 和 PureComponent 可以避免不必要的重复渲染,但是还是增加了一层 shallowEqual 的调用,造成多余的浪费。

浙公网安备 33010602011771号