美文网首页
setState 总结

setState 总结

作者: baxiamali | 来源:发表于2019-07-16 16:43 被阅读0次

引子:先来提神醒脑一下:

class Example extends React.Component {
  constructor() {
    super();
    this.state = {
      secretNumber: 10
    };
  }
  
  componentDidMount() {
    this.setState({secretNumber: this.state.secretNumber + 1});
    console.log(this.state.secretNumber);    // 第 1 次 log

    this.setState({secretNumber: this.state.secretNumber + 1});
    console.log(this.state.secretNumber);    // 第 2 次 log

    setTimeout(() => {
      this.setState({secretNumber: this.state.secretNumber + 1});
      console.log(this.state.secretNumber);  // 第 3 次 log

      this.setState({secretNumber: this.state.secretNumber + 1});
      console.log(this.state.secretNumber);  // 第 4 次 log
    }, 0);
  }

  render() {
    return null;
  }
};

快写下你的答案,十行后公布答案~~~











答案(10 10 12 13)

OK 以下是知识点总结


setState的异步性

  1. 调用 setState 其实是异步的 —— 不要指望在调用 setState 之后,this.state 会立即映射为新的值。
  2. setState() 视为请求而不是立即更新组件的命令。
  3. setState() 并不总是立即更新组件。它会批量推迟更新。这使得在调用 setState() 后立即读取 this.state 成为了隐患。

典型示例:

incrementCount() {
  // 注意:这样 *不会* 像预期的那样工作。
  this.setState({count: this.state.count + 1});
}

handleSomething() {
  // 假设 `this.state.count` 从 0 开始。
  this.incrementCount();
  this.incrementCount();
  this.incrementCount();
  // 当 React 重新渲染该组件时,`this.state.count` 会变为 1,而不是你期望的 3。

  // 这是因为上面的 `incrementCount()` 函数是从 `this.state.count` 中读取数据的,
  // 但是 React 不会更新 `this.state.count`,直到该组件被重新渲染。
  // 所以最终 `incrementCount()` 每次读取 `this.state.count` 的值都是 0,并将它设为 1。

  // 问题的修复参见下面的说明。
}

如果你需要基于当前的 state 来计算出新的值,该怎么办?

incrementCount() {
  this.setState((state) => {
    // 重要:在更新的时候读取 `state`,而不是 `this.state`。
    return {count: state.count + 1}
  });
}

handleSomething() {
  // 假设 `this.state.count` 从 0 开始。
  this.incrementCount();
  this.incrementCount();
  this.incrementCount();

  // 如果你现在在这里读取 `this.state.count`,它还是会为 0。
  // 但是,当 React 重新渲染该组件时,它会变为 3。
}
  1. setState() 的第二个参数为可选的回调函数,它将在 setState 完成合并并重新渲染组件后执行。通常,我们建议使用 componentDidUpdate() 来代替此方式。

总结: 调用 setState() 后立即读取 this.state,更新依赖于当前的 statestate需要特别注意。需要采取updater()函数,回调函数或者 componentDidUpdate()方案处理。

setState 什么时候是异步的

  1. 目前,在事件处理函数内部的 setState 是异步的。

如果 Parent 和 Child 在同一个 click 事件中都调用了 setState ,这样就可以确保 Child 不会被重新渲染两次。取而代之的是,React 会将该 state “冲洗” 到浏览器事件结束的时候,再统一地进行更新。这种机制可以在大型应用中得到很好的性能提升。

  1. 除此之外的setState调用会同步执行this.state
    所谓“除此之外”,指的是绕过React通过addEventListener直接添加的事件处理函数,还有通过setTimeout/setInterval产生的异步调用。

原因:在React的setState函数实现中,会根据一个变量isBatchingUpdates判断是直接更新this.state还是放到队列中回头再说,而isBatchingUpdates默认是false,也就表示setState会同步更新this.state,但是,有一个函数batchedUpdates,这个函数会把isBatchingUpdates修改为true,而当React在调用事件处理函数之前就会调用这个batchedUpdates,造成的后果,就是由React控制的事件处理过程setState不会同步更新this.state

setState 简化调用栈 图例

68747470733a2f2f696d672d626c6f672e6373646e696d672e636e2f32303139303231313134313432343733312e6a70673f782d6f73732d70726f636573733d696d6167652f77617465726d61726b2c747970655f5a6d46755a33706f5a57356e6147567064476b2c736861646f775f31302c746578745.jpeg

总结:在React中,如果是由React引发的事件处理(比如通过onClick引发的事件处理),调用setState不会同步更新this.state,除此之外的setState调用会同步执行this.state。所谓“除此之外”,指的是绕过React通过addEventListener直接添加的事件处理函数,还有通过setTimeout/setInterval产生的异步调用。

相信看到这里,大家已经明白为何答案为10 10 12 13 。

相关文章

  • react setState解读

    react setState解读 总结:看似同步,实则异步。 setState(updater, callback...

  • setState 总结

    引子:先来提神醒脑一下: 快写下你的答案,十行后公布答案~~~ 答案(10 10 12 13) OK 以下是知识点...

  • setState总结

    1. 前言 总结下setState用法不要直接修改 State 2. 第一个参数是函数 state的更新异步的,...

  • setState机制总结

    1.setState异步更新 不要直接修改state调用setState不会直接修改当前的state,而会将改变放...

  • react生命周期

    旧版声明周期 总结: 组件挂载时 setState流程 forceUpdate 强制更新 父组件render 新版...

  • react拓展

    setState() setState更新状态的2种方式 对象式的setState 函数式的setState 对象...

  • React setState 整理总结

    先看一个例子 假如有这样一个点击执行累加场景: 每一次点击, 累加三次,看一下输入: 并没有达到预期的效果,纠正也...

  • setState()状态更新函数

    理解setState的关键 setState不会立刻改变React组件中state的值; setState通过引发...

  • 08react基础-react原理

    setState()更新数据 setState()更新数据是异步的 注意:使用该语法,后面的setState不要依...

  • 『react』setState()特性

    一.setState()更新数据 由于setState()更新数据是异步的,所以后面的setState()不要依赖...

网友评论

      本文标题:setState 总结

      本文链接:https://www.haomeiwen.com/subject/sshtlctx.html