React 中的setState(arg1,arg2)异步操作
arg1可传入两种参数:
一种是对象
this.setState({
isAuthenticated: props.isAuthen
});
一种是函数
this.setState((preState, props) => {
return {isAuthenticated: props.isAuthen}
});
// 等价于上面的方法
this.setState((preState, props) => ({
isAuthenticated: !preState.isAuthenticated
}));
arg2为更改state之后的回调方法,arg2可为空
this.setState((preState, props) => {
console.log(preState)
return {isAuthenticated: true}
}, () => console.log(this.state.isAuthenticated));
//这个写法意思就是,在改变state中的数据之前,打印出当前的state,然后在更新state之后,
//利用回调打印出this.state.isAuthenticated
调用setState,组件的state并不会立即改变,setState只是把要修改的状态放入一个队列中,React会优化真正的执行时机,并且React会出于性能原因,可能会将多次setState的状态修改合并成一次状态修改。所以不要依赖当前的State,计算下个State。
例子:
function incrementMultiple() {
this.setState({count: this.state.count + 1});
this.setState({count: this.state.count + 1});
this.setState({count: this.state.count + 1});
}
直观上来看,当上面的incrementMultiple函数被调用时,组件状态的count值被增加了3次,每次增加1,那最后count被增加了3,但是,实际上的结果只给state增加了1。
原因并不复杂,就是因为调用this.setState时,并没有立即更改this.state,所以this.setState只是在反复设置同一个值而已,上面的code等同下面这样:
function incrementMultiple() {
const currentCount = this.state.count;
this.setState({count: currentCount + 1});
this.setState({count: currentCount + 1});
this.setState({count: currentCount + 1});
}
currentCount就是一个快照结果,重复地给count设置同一个值,不要说重复3次,哪怕重复一万次,得到的结果也只是增加1而已。
要想结果拿到3,则可以使用以下方法:
_bsetIncrementMultiple = () => {
this.setState(prevState => ({
count: prevState.count + 1
}));
this.setState(prevState => ({
count: prevState.count + 1
}));
this.setState(prevState => ({
count: prevState.count + 1
}));
}
这样,每一次改变count的时候,都是prevState.count + 1,pervState是前一个状态,每次setState之后,前一个状态都会改变,那么这时候,结果就是想要的3了。如果需要立即setState 那么传入一个函数来执行setState是最好的选择