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

2024-03-09

正如中所解释的这个问题 https://stackoverflow.com/a/54496445/1804173,React 在 React 事件处理程序中批处理状态更新调用。

如果状态更新是从基于 React 的事件(例如按钮单击或输入更改)中触发的,React 当前将批量状态更新。如果更新是在 React 事件处理程序之外触发的,例如异步调用,它不会批量更新。

I.e., a setFoo and setBar当从 React 事件处理程序回调中调用时,将融合在一起。

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

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

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

Edit: 我不想知道这个的原因是为了确保Foo and Bar出于一致性原因,更新是原子的。当然,我可以将状态融合在一起,但这会带来性能问题,因为setFooAndBar触发太多组件重新渲染,这当然可以通过进一步记忆来缓解......如果我能证明这一点setFoo and setBar始终使用更新批处理运行状态分离是合理的。


有没有办法手动检查状态更新是否是批量的,或者等效地,是否在 React 事件处理程序中执行某些代码?

只需登录renderfunction(函数组件体),当批处理发生时,你将得到一个日志而不是两个。

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


请注意,即使在非 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>
    </>
  );
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

检测状态更新是否在 React Hooks 中批量进行? 的相关文章

  • 由于 apollo-client 未定义,无法解构 GraphQL 查询?

    我正在寻找调试与错误消息相关的问题 未捕获的类型错误 无法解构 0 apollo client WEBPACK IMPORTED MODULE 4 useQuery 因为它未定义 Context 我正在为我的 React js 项目设置后端
  • 以编程方式填写reactjs表单

    我正在编写一个用户脚本 但无法填写由reactjs制作的表单 我的代码 document querySelector id username value email protected cdn cgi l email protection
  • 如何在react-bootstrap中禁用表单提交的

    在下面的代码片段中 我有许多文本类型的输入表单 如果用户点击 我似乎会得到相同的合成事件 就像他们按下提交按钮一样 我想忽略作为表单提交 只允许一个人按下 提交 按钮 我删除了一些表单组以减少示例 在所有情况下 按钮或 ENTER 键 e
  • 使用 ApolloClient 从 useContext 挂钩导入一个简单变量

    我的反应相对较新 似乎无法导入client来自上下文的变量 我有一个名为 federation tsx 的文件 其中包含一些代码 我相信这应该是相关部分 const link createHttpLink uri process env U
  • 在复选框内映射复选框 ReactJS

    我有一个函数 一旦主复选框被选中 就会触发子复选框 并且所有这些复选框都是从 JSON 映射的 主复选框 最高级别 及其下面的所有子复选框 第二级别 都会在单击时显示 并且效果很好 我想要显示的是单击时主复选框 第三级别 的子复选框2 级项
  • SWC with JavaScript:如何处理 CSS 导入以及如何绝对导入?

    TL DR 如何告诉 SWC 编译 React 组件中导入的 CSS 文件 如何告诉 SWC 在测试和 React 组件中编译绝对导入 这是一个最小的可重现示例 https github com janhesters riteway swc
  • 如何从CDN注入外部JS到Jest单元测试?

    我有 npm 和 webpack 的反应应用程序 我正在尝试向其添加单元测试 我使用的是包含在我的index html 中的CDN 的jQuery 而不是使用节点模块 我在组件中使用 jQueryTest1我向其中添加了单元测试用例 现在
  • React:设置 State 或设置 Prop 而无需重新渲染

    Problem 目前 我有一个LoginForm具有 成功 处理函数的组件handleOnSuccess 然后将其链接到父组件onTokenUpdate由 令牌更新 处理函数定义的属性handleUpdateToken 问题是setStat
  • 如何使用 Typescript 将 jest.spyOn 与 React 函数组件一起使用

    我正在使用 Typescript 和 hooks 开发一个 React 应用程序 并且尝试使用 Enzyme 和 Jest 来测试功能组件 我无法使用 jest spyOn 来测试我的组件中的方法 jest spyOn 方法无法正确解析并在
  • 如何使用 next.js 将动态 html 元素注入到页面?

    如何使用next js动态注入html元素到页面 这些元素未知类型 例如 输入 复选框 img 使用返回 json 类型的 api 指定此元素 如下所示 id rooms title Rooms order 1 type string wi
  • Typescript 和 React:在组件之间传递 props 与默认 props

    我对 Typescript 和使用 Typescript 创建 React 应用程序相当陌生 我在将道具从一个组件传递到另一个组件时遇到了一些麻烦 我在下面提供了一个示例 我的问题是围绕组件的默认道具 当我在父组件中调用子组件时 出现错误
  • 内的 ref={register} 给了我一个 path.split 错误

    嗨 我正在尝试用 React 制作一个表单 当我输入 ref register inside
  • 将 useRef 挂钩传递给 ref 属性的正确方法

    我不确定如何更明确地提出这个问题 但它是关于值传递 and 引用传递反应中的情况 还有胡克斯 我正在使用 gsap 来制作 div 滑入和滑出的动画 这是其上下文 但我猜测 ref 的用途并不重要 因此 这工作得很好 尽管这是一种更典型的类
  • React router.push 和 router.replace 之间的区别?

    有什么区别React 路由器推送 and 路由器 替换 路由器历史记录就像一个stack of routes 当您使用router replace 您将覆盖堆栈的顶部 当使用router push 它在顶部添加了一条新路线stack 路由器
  • AppBar 在 React 路由之间消失

    我有一个几乎可以工作的简单反应路由项目 我有一个AppBar and a Drawer 使用穆伊 抽屉里有三个项目 它们将重新路由应用程序 我的路由工作正常 但我遇到的问题是AppBar 因此一旦您进入某个页面 应用程序其余部分的导航就不再
  • React Material UI CardMedia 视频组件未播放

    我看到缩略图 但无法启动或停止视频 还有什么方法可以让它自动播放和重复吗 https material ui com api card media https material ui com api card media
  • Firebase 托管部署失败

    Running firebase deploy在给我一个超时错误之前会运行几分钟Error ESOCKETTIMEDOUT 我之前已经成功部署了多次 除了项目的前端 用 React 编写 之外 没有更改任何内容 我有一个单独的文件夹 其中包
  • 使用 useReducers 调度函数发送多个操作?

    使用时是否可以通过调度函数发送多个动作useReducer挂钩反应 我尝试向它传递一组操作 但这会引发未处理的运行时异常 明确地说 通常会有一个初始状态对象和一个减速器 如下所示 const initialState message1 nu
  • firebase :: 无法读取 null 的属性“props”

    你好 我正在尝试将react router与firebase一起使用 但它给了我这个错误 无法读取 null 的属性 props 这正是代码 我正在其中使用我的反应路由器 向下代码位于作为登录面板组件的组件上 else if this em
  • 在 React 中实现 Google 登录错误 -

    我正在尝试在 React 中实现 google 登录 这是我的组件 import Fragment useEffect from react import GOOGLE CLIENT ID from some file const Goog

随机推荐