【问题标题】:How does update to state internally using setState in react?使用 setState 在内部更新状态如何反应?
【发布时间】:2020-01-12 00:06:57
【问题描述】:

在 React 中,我们使用setState 来更新组件的状态。 setState 是一个异步进程,所以如果我们在同一个函数中有多个 setState

问题:内部如何处理批量更新?


场景 1:

componentDidMount 的 for 循环中更新状态,但在同一执行周期中。

class TodoApp extends React.Component {
  constructor(props) {
    super(props)
    var state = { count: 0 };
    Object.defineProperty(this, 'state', {
    	set: function(value) { console.log('called', value.count); state = value },
      get: function() { return state; }
    })
  }
  
  test() {
  	for (let i = 0; i< 1000; i++) {
      this.setState({ count: i });
    }
  }
  
  componentDidMount() {   
    this.test();
  }
  
  render() {
    return (
      <div>
        { this.state.count }
      </div>
    )
  }
}

ReactDOM.render(<TodoApp />, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>

场景 2:

componentDidMount 的 for 循环中更新状态,但执行周期不同。

class TodoApp extends React.Component {
  constructor(props) {
    super(props)
    var state = { count: 0 };
    Object.defineProperty(this, 'state', {
    	set: function(value) { console.log('called', value.count); state = value },
      get: function() { return state; }
    })
  }
  
  test() {
  	for (let i = 0; i< 1000; i++) {
      this.setState({ count: i });
    }
  }
  
  componentDidMount() {   
    setTimeout(this.test.bind(this), 0);
  }
  
  render() {
    return (
      <div>
        { this.state.count }
      </div>
    )
  }
}

ReactDOM.render(<TodoApp />, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>

如果您注意到场景 1 和 2,则在场景 1 中仅执行 2 次更新(假设 1 用于初始更新,其他用于最终更新)。但是,在场景 2 中,每个 setState 的状态都会发生变化/更新。

那么异步更新是如何工作的?什么定义了批量更新操作?

【问题讨论】:

  • React 仅在同步以及在事件处理程序或生命周期方法中使用时批量更新状态。永远不会。

标签: javascript reactjs


【解决方案1】:

如果您想使用 setState 进行批量更新,那么您应该使用同步 setState。有一种预定义的方式可以使我们的 setState 同步。

我对你的解释有点困惑,但根据 react 文档本身所说,我们不应该将多个状态设置为一个函数。因为它会导致每次重新渲染。不过,这不是一个好方法。

所以这里是您想要设置的计数状态,但以同步方式。 那么你可能更喜欢

this.setState(prevState=>{
const {count}=prevState;
//perform any action with this count state and at the end 
return {...prevState,count};})

希望这种方法可以帮助你。

【讨论】:

    【解决方案2】:

    如果您在 React 事件处理程序中,它们将被一起批处理。 React 批处理在 React 事件处理程序期间完成的所有 setState,并且 在退出自己的浏览器事件处理程序之前应用它们。

    setTimeout 不是 React 事件处理程序,因此 React 不会在 setTimeout 回调中批量更新状态(场景 2)。

    参考:https://github.com/facebook/react/issues/10231#issuecomment-316644950

    【讨论】:

      猜你喜欢
      • 2021-01-28
      • 2018-12-08
      • 2021-06-02
      • 2021-12-30
      • 1970-01-01
      相关资源
      最近更新 更多