在学习react的时,关于状态的生效时机,官方说明多个状态在同时执行的时候会被合并(批处理)。在学习hooks时,跟状态相关的useHooks
也以为是同样的批处理。如下面代码:
import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';
const Demo = () => {
const [a, setA] = useState('');
const [b, setB] = useState('');
useEffect(() => {
console.log('触发更新拉');
}, [a, b]);
return (<span onClick={() => {
setA(String(Math.random()));
setB(String(Math.random()));
}}>测试</span>);
};
ReactDOM.render(
<Demo />,
document.getElementById('container'),
);
再点击时会发现只触发一次,状态的set函数被批处理了。
但将上面的代码改动一下:
import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';
const Demo = () => {
const [a, setA] = useState('');
const [b, setB] = useState('');
useEffect(() => {
console.log('触发更新拉');
}, [a, b]);
return (<span onClick={() => {
setTimeout(() => {
setA(String(Math.random()));
setB(String(Math.random()));
}, 300);
}}>测试</span>);
};
ReactDOM.render(
<Demo />,
document.getElementById('container'),
);
此时点击后,会发现触发了两次更细,状态的set函数不批处理了!
查阅资料后发现,这是react hooks机制的一个缺陷,会计划在react 18中修复,说明文档在这:
https://github.com/reactwg/react-18/discussions/21
根据说明文档所说,不仅仅setTimeout
批处理会失效,像Promise.then
函数中也会失效。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。