第六十周总结——React数据管理

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

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
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值