React 18发布之后,新增了许多性能优化的特性,其中一项减少页面re-render的特性,值得关注一下!

Automatic batching

在 React 中使用setState来进行dispatch组件的State变化,当setState在组件中被调用后,并不会立即触发重新渲染。React 会执行全部事件处理函数,然后触发一个单独的re-render,合并所有的更新。
比如在点击+1的例子中,如果方法里连续触发三次setState,最终React会将更新函数放到一个队列里,然后合并队列触发setState的re-render,这就是batching的含义。

优点:既能减少程序数据状态存在中间值导致的不稳定性,也能提高渲染性能。

在React 18 之前,如果在回调函数的异步调用(setTimeout、then...)中,执行setState,由于丢失上下文(也就是所说的同步),无法做合并处理,所以每次setState调用都会触发一次re-render。
比如:

setTimeout(() => {
  setA('2'); // render次数+1
  setA('3'); // render次数+1
}, 0)

在react 18中这种情况,会默认进行合并处理!
比如:

setTimeout(() => {
   setB('2');
   setB('3'); // 两次set,只会render一次
 }, 0)

but,如果你真的需要进行两次render,react也提供给你了相应的方法~

import { flushSync } from 'react-dom';

...
setTimeout(() => {
   flushSync(() => {
     setB('2');
   })
   flushSync(() => {
     setB('3');
   })
 }, 0)
...

*注意!!这里要留意一下,如果这么写,flushSync是不会生效的!!!!*

setTimeout(() => {
   flushSync(() => {
     setB('2'); // render次数+1
     setB('3'); // render次数+1
   })
 }, 0)

起风了
120 声望35 粉丝

北冥有鱼,其名为鲲。鲲之大,不知其几千里也;化而为鸟,其名为鹏。鹏之背,不知其几千里也;怒而飞,其翼若垂天之云。是鸟也,海运则将徙于南冥。南冥者,天池也。