搜索
您的当前位置:首页正文

Batch入门

来源:榕意旅游网

简介

React 将多个状态更新分组到一个重新渲染中以获得更好的性能。

  • 减少中间状态,提高系统稳定性。
  • 提升渲染性能。

变动

18 以前

同步代码块的会合并,promisesetTimeoutevent回调函数中会立刻渲染不会进行合并。

18 以后

任何情况都可以合并渲染了,包括 promisesetTimeoutevent

如果需要调用后立即重新渲染,使用flushSync包裹。

批量更新逻辑

class 类组件

import React from 'react';
import { Button, Space } from 'antd';

export default class ClassCom extends React.Component {
  
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    }
  }
  
  handlerClick = () => {
    this.setState({ count: this.state.count + 1 });
    console.log(this.state.count);
    
    setTimeout(() => {
      console.log(this.state.count);
      this.setState({ count: this.state.count + 3 });
      console.log(this.state.count);
      this.setState({ count: this.state.count + 4 });
      console.log(this.state.count);
    }, 0);
    
    this.setState({ count: this.state.count + 2 });
    console.log(this.state.count);
  }
  
  render() {
    return (
      <div>
        <Space>
          <Button onClick={this.handlerClick}>setState click</Button>
          <p>count: {this.state.count}</p>
        </Space>
      </div>
    );
  }
}

React@18 渲染结果

// console 打印
0
0
2
2
2

// 最终 count 结果
6
// 0 + 1
// 0 + 2
// 2 + 3
// 2 + 4

React@17 渲染结果

import React, { useState } from 'react';
import { Button, Space } from 'antd';

export default function HooksCom() {
  const [count, setCount] = useState(0);

  const handlerClick = () => {
    setCount(count + 1);
    console.log(count);

    setTimeout(() => {
      console.log(count);
      setCount(count + 3);
      console.log(count);
      setCount(count + 4);
      console.log(count);
    }, 0);

    setCount(count + 2);
    console.log(count);
  };
  return (
    <div>
      <Space>
        <Button onClick={handlerClick}>useState click</Button>
        <p>count: {count}</p>
      </Space>
    </div>
  );
}

React@18 渲染结果

React@17 渲染结果

这里为什么 react@18 中,函数组件的输出结果为 0 0 0 0 0 渲染 4,而类组件输出结果为 0 0 2 2 2渲染 6

类组件中,this.state.count 是会根据 this 而改变的。而函数组件中,countsetTimeout 中不会改变,所以一直是 0

批量更新 render 影响

添加一个 render 组件

import { useEffect } from 'react';
export default function RenderEl() {
  useEffect(() => {
    console.log('useEffect render');
  }, []);
  console.log('render');
  return null;
}

加到上面两种类型的组件中

<div>
  <Space>
    <Button onClick={this.handlerClick}>setState click</Button>
    <p>
      count: {this.state.count}
      <RenderEl />
    </p>
  </Space>

</div>

再次点击渲染观察打印结果。

class 类组件

React@18 渲染结果

React@17 渲染结果

function 函数组件

React@18 渲染结果

React@17 渲染结果

因篇幅问题不能全部显示,请点此查看更多更全内容

Top