批处理: 将多个状态更新合并到一个渲染中。
const Batching = () => {
const [isLoading, setIsLoading] = useState(false);
const [isDisable, setIsDisable] = useState(false);
const handleClick = () => {
setIsDisable(true);
setIsLoading(true);
};
useEffect(() => {
console.log("渲染");
}, [isDisable, isLoading]);
return (
<div>
{isLoading && "is loading!"}
{isDisable && "is disible"}
<button onClick={handleClick}>click</button>
</div>
);
};
export default Batching;
在React 17 中,点击事件触发会将两个状态更新只需要一次渲染。
这是因为在 React 17中只在浏览器事件(如点击)期间进行批量更新,但这里我们在事件已经处理后更新状态(在setTimeout中执行呢?)
const handleClick = () => {
setTimeout(() => {
setIsDisable(true);
setIsLoading(true);
});
};
发生两次渲染 :)
React 17 不会批处理外部事件处理程序。即 Promise、setTimeout或任何其他事件内部的更新不会在 React 中批处理。
自动批处理
在任何情况下都能进行批处理。
React 18 提供了 createRoot,所有更新都将自动批处理。进一步减少渲染提高了性能。
看看下面的🌰:
const handleClick = () => {
setIsDisable(true);
setTimeout(() => {
setIsLoading(true);
});
};
怎么渲染了两次 ??? setTimeout进入了 eventLoop!