【学点React】 1. setState什么时候异步,什么时候合并?

348 阅读1分钟

setState有时异步,有时同步,有时合并,有时不合并。

  • 正常调用时是异步的,在setTimeout和自定义Dom事件里是同步的。
  • 传入对象时会被合并,传入函数时不合并。

1. 异步(普通使用)

this.setState({
    count: this.state.count + 1
}, () => {
    console.log('count by callback', this.state.count) // 回调函数中可以拿到最新的 state
})
console.log('count', this.state.count) // 异步的,拿不到最新值

2. 同步(setTimeout、Dom事件)

在setTimeout里是同步的

// setTimeout 中 setState 是同步的
setTimeout(() => {
    this.setState({
        count: this.state.count + 1
    })
    console.log('count in setTimeout', this.state.count)
}, 0)

在自己定义的dom事件里是同步的

componentDidMount() {
    // 自己定义的 DOM 事件,setState 是同步的
    document.body.addEventListener('click', this.bodyClickHandler)
}

3. 合并(对象形式)

传入对象,会被合并(类似 Object.assign )。执行结果只一次 +1


this.setState({
    count: this.state.count + 1
})
this.setState({
    count: this.state.count + 1
})
this.setState({
    count: this.state.count + 1
})

4. 不合并(函数形式)

传入函数,不会被合并。执行结果是 +3

this.setState((prevState, props) => {
    return {
        count: prevState.count + 1
    }
})
this.setState((prevState, props) => {
    return {
        count: prevState.count + 1
    }
})
this.setState((prevState, props) => {
    return {
        count: prevState.count + 1
    }
})