Open artdong opened 5 years ago
1、setState(updater, [callback]), updater为返回stateChange对象的函数: (state, props) => stateChange 接收的state和props被保证为最新的。
2、setState(stateChange, [callback]) stateChange为对象, callback是可选的回调函数, 在状态更新且界面更新后才执行。
总结: 对象方式是函数方式的简写方式。如果新状态不依赖于原状态
,使用对象方式
;如果新状态依赖于原状态
,使用函数方式
;如果需要在setState()后获取最新的状态数据
, 在第二个callback函数中读取
。
class App extends Component {
this.state = { count: 0 }
componentDidMount() {
this.setState({val: 1}, () => {
// eslint-disable-next-line no-console
console.log(this.state.count); // 输出更新后的值 --> 1
});
}
}
1、setState只在合成事件和钩子函数中是“异步”的,在原生事件、setTimeout和promise中都是同步的。
setTimeout
class App extends Component {
this.state = { count: 0 }
componentDidMount() {
setTimeout(() => {
this.setState({ count: this.state.count+ 1 })
console.log(this.state.count) // 输出更新后的值 --> 1
}, 0)
}
}
promise
class App extends Component {
this.state = { count: 0 }
componentDidMount() {
Promise.resolve().then(() => {
this.setState({val: this.state.val + 1});
console.log('promise', this.state.val); // 输出更新后的值 --> 1
});
}
2、setState 的“异步”并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿到更新后的值,形成了所谓的“异步”,当然可以通过第二个参数 setState(partialState, callback) 中的callback拿到更新后的结果。
3、setState 的批量更新优化也是建立在“异步”(合成事件、钩子函数)之上的,在原生事件和setTimeout 中不会批量更新,在“异步”中如果对同一个值进行多次setState,setState的批量更新策略会对其进行覆盖,取最后一次的执行,如果是同时setState多个不同的值,在更新时会对其进行合并批量更新。
setState到底是异步还是同步?