1、setState 方法易犯错点。
- setState 不会立即改变 React 组件中的 state 的值。
- setState 通过引发一次组件的更新过程引发重新绘制。
- 多次 setState 函数调用产生的效果会合并。
2、setState 方法
在 React 中,一个组件要读取当前的状态只需要访问 this.state 属性,但是更新状态需要调用 this.setState() 方法。
// 读取状态
this.state.xxx
// 更新状态
this.setState({...});
若使用 this.state.xxx
赋值更新状态,的确能够改变状态,但是无意义,也不会触发重新渲染。
因为,this.state 只是一个对象,单纯去修改一个对象的值无意义,去驱动 UI 的更新才是有意义的。
而 setState 方法被调用时,能驱动组件的更新过程,引发 shouldComponentUpdate、componentWillUpdate、 reader、 componentDidUpdate 等一系列方法调用,完成 UI 更新。
3、setState 不会立刻改变 React 组件中的 state 值。
// 初始化
this.state = {
count: 0
};
// 操作
let count = this.state.count;
console.log(count);
this.setState({count: count + 1});
console.log(this.state.count);
// 输出 0 0
由于 setState
并不会立即修改 this.state
的值,所以调用完 this.setState
方法后获取 this.state.count
依旧是旧值 0。
4、setState 通过引发一次组件的更新过程来引发重新绘制
setState 方法被调用时,会引起 React 的 4 个生命周期的函数被调用:
- shouldComponentUpdate (this.state 没有得到更新)
- componentWillUpdate (this.state 没有得到更新)
- reader (this.state 得到更新)
- componentDidUpdate
(比修改 props 引发的生命周期少一个 componentWillReceiveProps 函数)。
当 shouldComponentUpdate 函数返回 false 时,更新过程将被打断,render 函数不会被调用,但是依旧会更新 this.state。
5、多次 setState 函数调用会合并
React 中利用队列机制来管理 state ,并且会将多个 state 合并,以避免不必要的渲染。
this.setState({FirstName: 'Mo'});
this.setState({LastName: 'Chen'});
上面代码连续调用了两次 this.setState,但是只会引发一次更新生命周期。因为 React 会将多个 this.state 产生的修改放在一个队列里。在每次更新过程中,会把积攒的 setState 结果合并,所以上述代码相当于:
合并 state 相当于 =>
this.setState({
FirstName: 'Mo',
LastName: 'Chen'
});
注意:由于多次调用 setState 会发生合并效果,所以当连续修改同一个状态时,新值将覆盖旧值。
this.setState({count: this.state.count + 1});
this.setState({count: this.state.count + 2});
上述代码的执行效果是,在 count 原有的基础上加 2,并不是 3,这也与 setState 函数异步有关,即不立刻修改 count 状态。
6、setState 接受函数参数
this.setState 可以接受一个函数参数。该函数有两参数:一个是当前的 state 值,第二个是当前的 props,该函数返回一个对象,这个对象代表想要对 this.state 的更改。
function increment(state, props){
return {count: state.count + 1};
}
this.setState(increment);
可以看到,此时计算新状态的值不在依赖于 this.state 而是依赖于参数 state。借助该方法就可以连续修改同一状态。
this.setState(increment);
this.setState(increment);
this.setState(increment);
上面代码调用三次 setState 的结果是 this.state.count 的值加 3。这是因为 React 会保证每次调用 increment 时,state 都已经合并了之前的状态修改结果。
注意:当使用对象做 setState 方法参数和使用函数做 setState 方法参数时,使用对象参数的 setState 方法会将状态还原。
this.setState(increment);
this.setState(increment);
this.setState({count: this.state.count + 1});
this.setState(increment);
上面代码执行完 this.state.count 加 2 ,不是 4。