react 更新最新状态值
In both hooks and class components, we have several ways to construct and alter the component’s state. We change the state by calling setState
or using useState
. These changes cause parts of the component to re-render, and possibly to its children.
在 hook和class组件中,我们都有几种方法来构造和更改组件的状态。 我们通过调用setState
或使用useState
更改状态。 这些更改会导致组件的某些部分重新呈现,甚至可能会呈现给其子代。
An interesting mechanism of React, which is not mentioned much, is the state batch updating. Instead of one by one, React does batch updates, reducing the number of component renders.
状态批处理更新是React的一个有趣的机制,它很少被提及。 React不会一一对应地进行批处理更新,从而减少了组件渲染的数量。
In this article, we will examine how and when this happens, using examples.
在本文中,我们将使用示例检查发生这种情况的方式和时间。
类组件状态 (Class components state)
Using class components we have the component’s single state object, which we usually update using a single this.setState
command. Take this for example.
使用类组件,我们具有组件的单个状态对象,通常使用单个this.setState
命令对其进行更新。 以这个为例。
挂钩状态 (Hooks state)
However, when using hooks, the situation is more complex.
但是,使用钩子时,情况更加复杂。
Using useState
we have several options to construct the state of the component.
使用useState
我们有几个选择来构造组件的状态。
- Use a single state object, and work with it just like the previous class component example. 使用单个状态对象,并像前面的类组件示例一样使用它。
- Split the state into singular properties. 将状态拆分为单个属性。
- Or divide the state into several state variables related to each other. 或者将状态分为几个相互关联的状态变量。
当将类组件重构为钩子时… (When refactoring class component into hooks…)
Since the release of hooks with React 16.8, there has been a heated debate in the React community regarding their use vs the old-school class components.
自从在React 16.8中发布钩子以来,React社区一直在激烈讨论它们的使用和老式类组件。
When refactoring a class-based component into hook functional component, there are all sorts of things to consider, one of them is how to construct the state.
在将基于类的组件重构为hook功能组件时,需要考虑各种各样的事情,其中之一是如何构造状态。
“We recommend to split state into multiple state variables based on which values tend to change together”, according to React regarding to Hooks.
根据关于钩子的React所说 ,“我们建议根据状态值一起变化将状态分为多个状态变量”。
Recently a co-worker asked me, how to properly migrate such class component into a hooks function component, and how to divide its new state.
最近,一位同事问我,如何将此类类组件正确地迁移到一个钩子函数组件中,以及如何划分其新状态。
My first answer, as recommended by React, was similar to the above. But actually, I did not feel comfortable with this answer.
根据React的建议,我的第一个答案与上述类似。 但是实际上,我对这个答案并不满意。
How can we know in advance which variables tend to change together? And besides that, a future feature may force us to change them apart, and consequently build the state differently.
我们如何预先知道哪些变量会一起变化? 除此之外,未来的功能可能会迫使我们将它们分开,从而以不同的方式构建国家。
Finally, I suggested him, divide the state into separate individual variables.
最后,我建议他将状态分为单独的各个变量。
His next and obvious question was, “When we have a state with discrete variables, we will have to change them separately and thus cause unnecessary re-renders. Wouldn’t it impair the performance of the application?”.
他的下一个显而易见的问题是:“当我们的状态中包含离散变量时,我们将不得不分别更改它们,从而导致不必要的重新渲染。 会不会损害应用程序的性能?”。
React批量更新 (React batch updating)
“React may batch multiple setState()
calls into a single update for performance”, according to React’s documentation.
根据React的文档 , “ React可以将多个setState()
调用批处理到单个更新中以提高性能”。
Batch updating is a React’s interesting feature, that combines state updates.
批量更新是React的有趣功能,它结合了状态更新。
The main idea is that no matter how many setState
calls you make inside a React event handler or synchronous lifecycle method, it will be batched into a single update. That is only one single re-render will eventually happen.
主要思想是,无论您在React 事件处理程序或同步生命周期方法中进行多少setState
调用,它都将被批处理成一个更新。 最终只有一次重新渲染。
This functionality is relevant for both hooks and regular class components, and its purpose is to prevent unnecessary rendering.
此功能与钩子和常规类组件都相关,其目的是防止不必要的呈现。
“Currently (React 16 and earlier), only updates inside React event handlers are batched by default” , according to Dan Abramov.
“目前(React 16和更早版本),默认情况下,仅批处理React事件处理程序中的更新”,根据Dan Abramov的说法。
批量更新示例 (Batch update example)
Take a look at the next example.
看下一个例子。
A function component, which at the click of its button, changes the three individual states of the component one after the other.
一个功能组件,通过单击其按钮,可以一个接一个地更改组件的三个单独状态。
On contrary to what one might think, on click, the component renders only once, although the three states change separately.
与人们可能想到的相反,单击时,该组件仅呈现一次,尽管这三种状态分别更改。
This is possible thanks to batch updating.
由于批量更新,这是可能的。
The same holds for class components. Separate changes to the state within the event handler will result in a single rendering.
类组件也是如此。 事件处理程序中状态的单独更改将导致单个呈现。
在哪些情况下批量更新有效? (In which cases does batch updating works?)
As mentioned, batch updating should work inside event handlers. But it actually works in other methods too.
如前所述,批处理更新应该在事件处理程序中起作用。 但是它实际上也可以用其他方法工作。
In this example, you can see how to batch updating works within useEffect
.
在此示例中,您可以看到如何在useEffect
进行批量更新。
And here you can see that setState
is called inside componentDidMount
which causes only one extra update (and not three).
在这里您可以看到setState
在componentDidMount
内部被调用,这只会导致一个额外的更新(而不是三个)。
但这并不是在所有情况下都有效... (But it doesn’t work in every situation…)
Note that this functionality does not always work. In an event handler that uses an asynchronous operation of different kinds, such as async/await
, then/catch
, setTimeout
, fetch
, etc. Separate state updates will not be batched.
请注意,此功能并不总是有效。 在使用不同类型的异步操作(例如async/await
, then/catch
, setTimeout
, fetch
等)的事件处理程序中。单独的状态更新将不被批处理。
In this case, on every click, instead of one render, we get three.
在这种情况下,每单击一次,我们就会得到三个,而不是一个渲染。
如何强制批处理? (How to force batching?)
Fortunately, we can overcome this by using ReactDOM.unstable_batchUpdate
, And still benefit from state batched updates as needed.
幸运的是,我们可以通过使用ReactDOM.unstable_batchUpdate
克服这一ReactDOM.unstable_batchUpdate
,并且仍然可以根据需要从状态批处理更新中受益。
This is how it’s done.
这是完成的方式。
Although this function is supposedly “unstable”, React apparently intends to address this in the following versions.
尽管此功能据说“不稳定”,但React显然打算在以下版本中解决此问题。
“In future versions (probably React 17 and later), React will batch all updates by default so you won’t have to think about this”, according to Dan Abramov.
Dan Abramov表示: “在未来的版本中(可能是React 17及更高版本),React将默认批处理所有更新,因此您不必考虑这一点。”
结论 (Conclusion)
Working with either React hooks and class components, it is worth getting to know this cool feature, which helps us manage the state, effortlessly, and in a performant way.
无论是使用React钩子还是使用类组件,都值得了解这个很酷的功能,它可以帮助我们轻松,高效地管理状态。
I hope this post helped you to understand how you can update the state in a smarter and clearer way.
我希望这篇文章可以帮助您了解如何以更智能,更清晰的方式更新状态。
Have a great day! Thanks for reading! 🎾
祝你有美好的一天! 谢谢阅读! 🎾
翻译自: https://medium.com/swlh/react-state-batch-update-b1b61bd28cd2
react 更新最新状态值