React数据管理
React批量更新
React中的批量更新就是将多次更新合并处理,最终只渲染一次,来获得更好的性能。
React18版本之前的批量更新
// react 17 react-dom 17 react-scripts 4.0.3
import * as ReactDOM from "react-dom";
import {
useState} from 'react'
function App() {
const [num1, setNum1] = useState(0);
const [num2, setNum2] = useState(0);
function handleClick() {
setNum1(c => c + 1);
setNum2(c => c + 1);
}
console.log("render");
return (
<div>
num1:{
num1}-num2:{
num2}
<button onClick={
handleClick}>Next</button>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
点击一次按钮触发setNum1和setNum2,但是render只输出一次,React将多次更新合并处理,最终只渲染一次。
然而React18版本之前,批量更新并不是所有场景都会生效。
import * as ReactDOM from "react-dom";
import {
useState} from 'react'
function App() {
const [num1, setNum1] = useState(0);
const [num2, setNum2] = useState(0);
function handleClick() {
setTimeout(()=>{
setNum1(c => c + 1);
setNum2(c => c + 1);
})
}
console.log("render");
return (
<div>
num1:{
num1}-num2:{
num2}
<button onClick={
handleClick}>Next</button>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
点击一次按钮触发setNum1和setNum2,然后会输出两次render,这就是在React18版本之前,React的批量更新失效了。
总结:在React18之前,我们只能在React事件处理函数中执行过程中进行批量更新。对于promise、setTimeout、原生事件处理函数或其他任何事件中的状态更新都不会进行批量更新。
React18自动批量更新
从React18的createRoot开始,无论在哪里,所有更新都将自动进行批量更新。
这意味着 setTimeout、promises、原生事件处理函数或其他任何事件的批量更新都将与 React 事件一样,以相同的方式进行批量更新。我们希望这样可以减少渲染工作量,从而提高应用程序的性能:
// react 18.2.0 react-dom 18.2.0 react-scripts 5.0.1
import ReactDOM from 'react-dom/client';
import {
useState} from 'react'
function App() {
const [num1, setNum1] = useState(0);
const [num2, setNum2] = useState(0);
function handleClick() {
setTimeout(()=>{
setNum1(c => c + 1);
setNum2(c => c + 1);
})
}
console.log("render");
return (
<div>
num1:{
num1}-num2

React的批量更新机制在18版本之前和之后有所不同。在React18之前,批量更新主要在React事件处理函数中生效,而18版本开始,所有更新都将自动批量更新,包括setTimeout和Promise等场景。这有助于提高性能,但可能影响到某些同步行为。对于需要禁止批量更新的情况,可以使用flushSync。此外,对于Class组件,React18的异步更新可能改变状态更新的顺序和可见性。
最低0.47元/天 解锁文章
777





