在React 18发布之后,新增了许多性能优化的特性,其中一项减少页面re-render的特性,值得关注一下!
Automatic bacthing
在 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)