reactjs - 检测状态更新是否在 React Hooks 中批量进行?

标签 reactjs react-hooks

this question 中所述,React 在 React 事件处理程序中批处理状态更新调用。

React currently will batch state updates if they're triggered from within a React-based event, like a button click or input change. It will not batch updates if they're triggered outside of a React event handler, like an async call.

即,当从 React 事件处理程序回调中调用时,setFoosetBar 将融合在一起。

我正在处理各种第三方库,其中一些包装非 React JS 库。我正在向它们传递回调,我想知道这些回调是否属于“React 事件处理程序”类别,即状态更新批处理是否适用于它们。

有没有办法手动检查状态更新是否是批量的,或者等效地,是否在React事件处理程序中执行某些代码?我正在考虑进行临时检查,例如:

let callback = () => {
  // fictitious checks
  console.log(ReactDOM.checkIfUpdatesAreBatched());
  console.log(ReactDOM.checkIfRunningInReactEventHandler());
  setFoo("foo");
  setBar("bar");
}

编辑:我不想知道这一点的原因是为了确保 FooBar 更新是原子的,以保持一致性。当然,我可以将状态融合在一起,但这会带来性能问题,因为 setFooAndBar 会触发太多组件重新渲染,这当然可以通过进一步内存来缓解......如果我可以证明这一点setFoosetBar 始终以更新批处理方式运行,状态分离将是合理的。

最佳答案

Is there a way to manually check if state update is batched, or equivalently, whether some code is executed within a React event handler?

只需在 render 函数(函数组件主体)内登录即可,当批处理发生时,您将得到一个日志而不是两个。

确保只有此事件会导致重新渲染。


请注意,即使在非 React 事件中,批处理的常见解决方法是将状态移动到单个对象中。您还可以使用另一个 useEffect 并从中派生其他状态。

完整示例:

function Component() {
  const [a, setA] = useState("a");
  const [b, setB] = useState("b");

  console.log({ a });
  console.log({ b });

  const onClick = () => {
    setA("aa");
    setB("bb");
  };

  const onClickPromise = () => {
    Promise.resolve().then(() => {
      setA("aa");
      setB("bb");
    });
  };

  const [batch, setBatch] = useState({ a, b });

  const onClickPromiseBatched = () => {
    Promise.resolve().then(() => {
      setBatch({ a: "aa", b: "bb" });
    });
  };

  useEffect(() => {
    // Will get another render for deriving the state
    // Or just use only the batched state
    setA(batch.a);
    setB(batch.b);
  }, [batch]);

  return (
    <>
      <button onClick={onClick}>Render</button>
      <button onClick={onClickPromise}>Render with promise</button>
      <button onClick={onClickPromiseBatched}>
        Render with promise batched
      </button>
    </>
  );
}

Edit Batch Example

关于reactjs - 检测状态更新是否在 React Hooks 中批量进行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65370250/

相关文章:

reactjs - 如何防止在react-window的List组件内重新渲染子组件

reactjs - 如何在 React Material 中的列表项之间创建一个空格

javascript - ReactJS 如何在状态具有特定值时运行 API 调用

javascript - react Hook : maximum depth exceeded

javascript - 同构 react-router-redux syncHistory 中间件

javascript - 在ReactJs中删除Json的一些对象

reactjs - 将 socket.io 与 redux 结合使用

javascript - 在 Eslint 配置文件中禁用报价规则

javascript - 从 react js中的javascript对象列表中删除重复值

reactjs - 带有通用类型的自定义 Hook TypeScript