简体   繁体   English

如何使用setState在内部更新为内部状态?

[英]How does update to state internally using setState in react?

In React, we use setState to update the state of the component. 在React中,我们使用setState来更新组件的状态。 setState is an async process, so if we have multiple setState in same function. setState是一个异步过程,因此如果我们在同一函数中有多个setState

Question: How is the batching of update handled internally? 问题:如何在内部处理更新批处理?


Scenario 1: 方案1:

Updating the state in a for loop in componentDidMount but in same execution cycle. 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> 


Scenario 2: 方案2:

Updating the state in a for loop in componentDidMount but in different execution cycle. 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> 


If you notice scenario 1 and 2, in scenario 1 only 2 updates ( assuming 1 for initial update and other for final ) are performed. 如果您注意到方案1和2,则在方案1中仅执行2次更新( 假定1为初始更新,其他为final )。 However, in scenario 2, state is mutated/ updated for every setState. 但是,在方案2中,每个setState的状态都会发生突变/更新。

So how is the async update working? 那么异步更新如何工作? What defines the batch update action? 什么定义了批处理更新操作?

They will be batched together if you are inside a React event handler. 如果您在React事件处理程序中,它们将被一起批处理。 React batches all setStates done during a React event handler, and applies them just before exiting its own browser event handler. React批处理在React事件处理程序期间完成的所有setState,并在退出其自己的浏览器事件处理程序之前应用它们。

setTimeout is not a React event handler so React won't batch state updates inside a setTimeout callback (scenario 2). setTimeout不是React事件处理程序,因此React不会在setTimeout回调(方案2)内批处理状态更新。

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

If you want batchUpdate by using setState then you should go with sync setState. 如果要使用setState进行batchUpdate,则应使用同步setState。 There is a pre-defined way which can make our setState sync. 有一种预定义的方法可以使我们的setState同步。

I'm little confused with your explanation but as per react documentation says itself we should not set multiple state into one function. 我对您的解释不感到困惑,但是根据react文档的说法,我们本身不应该将多个状态设置为一个函数。 because it will cause to re-render every time. 因为它将导致每次重新渲染。 which is not a good approach though. 这不是一个好方法。

so here is your count state which you want to set but in a sync way. 因此这是您要设置的计数状态,但要以同步方式进行。 then you might prefer 那么您可能更喜欢

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

Hope this approach may help you. 希望这种方法可以为您提供帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM