react state 同步异步理解

64 阅读1分钟

首先在 setState 说的异步,指不能立刻获取到更新的数据 那么什么条件下会发生,何时又是同步的 这个分版本 在react 17中是 定时器,监听事件回调里都是同步的也就是说在里面设置完数据后,就能立刻获取到最新的数据。


          setTimeout(() => {
            this.setState({
              count: this.state.count + 1
            }, () => {
              console.log('callback', this.state.count)
            })
            console.log('state', this.state.count)
          }, 100);

但是在react 18 中,定时器,监听事件回调里都是异步加合并,也就是说,统一了行为。

合并

  1. 但是合并在react 版本中行为都是一致的
  2. 对于纯数值类型,多次更新,但是每次都是获取的初始值,可以理解为每次当前函数上下文,是同一个引用的是首次的初始值。
  3. 但是对于函数类型,那就不是,每次 都是在原有的基础上进行更新
class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      count: 0
    }
  }
  
 <button onClick={() => {

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

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

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

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

          // })
          console.log('state', this.state.count) // 1

          setTimeout(() => {
            this.setState({
              count: this.state.count + 1
            }, () => {
              console.log('callback', this.state.count)
            })
            console.log('state', this.state.count)
          }, 100);
        }}>点击</button>

不可变

  1. 本质上是说函数式编程里面的纯函数,同样的输入造成同样的输出,你直接修改了输入,那就可能难以追踪数据修改。
  2. 同时也为了性能优化,比如会常用immer.js
  3. 不过里面所提到的原理层面为何一定要用不可变,用了不可变又会发生什么
错误的做法:
this.state.obj1.a = 100
this.state.obj2.a = 100
this.setState({
    obj1: this.state.obj1,
    obj2: this.state.obj2
})
正确的做法:
this.setState({
    obj1: Object.assign({}, this.state.obj1, {a: 100}),
    obj2: {...this.state.obj2, a: 100}
})