Automatic batching in React 18

244 阅读1分钟

批处理: 将多个状态更新合并到一个渲染中。

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!

参考:React 18 性能提升之自动批处理减少渲染