machao07 / interview-questions

前端技术栈相关面试知识点( Vue、React、Typescript、JavaScript...),喜欢请点start

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

React中setState执行机制

machao07 opened this issue · comments

定义

  • 一个组件的显示形态可以由数据状态和外部参数所决定,而数据状态就是state
  • 当需要修改里面的值的状态,需要通过调用setState来改变,达到更新组件内部数据的作用

直接修改state的状态,视图不会更新原因

  • React并不像vue2中调用 Object.defineProperty数据响应式或者 Vue3调用 Proxy监听数据的变化
  • 必须通过 setState方法来告知react组件 state已经发生了改变

state方法的定义是从React.Component中继承,定义的源码如下

Component.prototype.setState = function(partialState, callback) {
  invariant(
    typeof partialState === 'object' ||
      typeof partialState === 'function' ||
      partialState == null,
    'setState(...): takes an object of state variables to update or a ' +
      'function which returns an object of state variables.',
  );
  this.updater.enqueueSetState(this, partialState, callback, 'setState');
};

更新类型

异步更新 (setState回调)

changeText() {
  this.setState({
    message: "你好啊"
  }, () => {
    console.log(this.state.message); // 你好啊
  });
}

同步更新(异步setTimeout)

changeText() {
  setTimeout(() => {
    this.setState({
      message: "你好啊
    });
    console.log(this.state.message); // 你好啊
  }, 0);
}

批量更新

handleClick = () => {
    this.setState({
        count: this.state.count + 1,
    })
    console.log(this.state.count) // 1

    this.setState({
        count: this.state.count + 1,
    })
    console.log(this.state.count) // 1

    this.setState({
        count: this.state.count + 1,
    })
    console.log(this.state.count) // 1
}

结果分析

  • 击按钮触发事件,打印的都是 1,页面显示 count 的值为 2

  • 对同一个值进行多次 setState, setState 的批量更新策略会对其进行覆盖,取最后一次的执行结果

如果是下一个state依赖前一个state的话,推荐给setState一个参数传入一个function

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