”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 状态测试用例中的 ReactDOM.unstable_batchedUpdates。

状态测试用例中的 ReactDOM.unstable_batchedUpdates。

发布于2024-11-09
浏览:685

在本文中,我们将研究 ReactDOM.unstable_batchedUpdates 在测试用例中的使用,特别是在 Zustand(React 的流行状态管理库)中。我们还将分解测试并解释批量更新如何通过最小化不必要的重新渲染来增强 React 的性能。

理解测试用例

这是我们将要检查的测试用例:

ReactDOM.unstable_batchedUpdates in Zustand’s testcase.

编写此测试用例是为了验证在将 Zustand 与 React 渲染系统一起使用时是否可以应用批量更新。

分解测试用例

1。 Zustand 商店设置: 第一步涉及使用创建功能创建 Zustand 商店:

const useBoundStore = create(
  (set) => ({   
  count: 0,   
  inc: () => set((state) => ({ count: state.count   1 })), }))

在这里,存储维护一个简单的状态,其中 count 属性初始化为 0,并有一个 inc 函数来递增计数。 set函数是Zustand更新状态的方式,类似于React中的setState。

2. Counter 组件: Counter 组件使用 useBoundStore 检索当前计数和 inc 函数:

const { count, inc } = useBoundStore()

此组件订阅商店的状态,对计数的任何更改都将导致其使用新值重新渲染。

3.使用 ReactDOM.unstable_batchedUpdates 提高性能: 在 useEffect 钩子内部, inc 函数在 ReactDOM.unstable_batchedUpdates 块中被调用两次:

useEffect(() => {   
  ReactDOM.unstable_batchedUpdates(() => {     
    inc()     
    inc()   
  }) 
}, [inc])

这就是奇迹发生的地方。通常,每次调用 inc() 都会触发一次单独的更新,从而导致两次渲染。然而,通过将这些调用包装在unstable_batchedUpdates中,React能够在一次更新中一起处理它们,从而只产生一次渲染。这通过减少渲染数量来优化性能,这在性能关键型应用程序中特别有用。

4。渲染组件并断言结果 最后渲染组件,测试等待计数达到 2:

const { findByText } = render(
       
    >, 
)  

await findByText('count: 2')

此断言确保在两次增量后,计数正确更新并呈现为“count:2”。

什么是 ReactDOM.unstable_batchedUpdates?

ReactDOM.unstable_batchedUpdates 是 React 提供的一种方法,允许在单个渲染周期中处理多个状态更新。默认情况下,React 批量更新在事件处理程序(例如单击事件)内触发,这意味着如果您更新多个状态以响应用户交互,React 将仅渲染组件一次。但是,在事件处理程序之外(例如在 setTimeout 或 useEffect 内),更新不会自动批处理。

但是在React 18之后这已经改变了。下面是从react.dev中挑选的屏幕截图

ReactDOM.unstable_batchedUpdates in Zustand’s testcase.

ReactDOM.unstable_batchedUpdates in Zustand’s testcase.

请记住,文档表明超时、承诺、本机事件处理程序或任何其他事件内部的更新将以与 React 事件内部的更新相同的方式进行批处理。但在 Zustand 的测试用例中,批量更新是在 useEffect` 内部应用的。这就是unstable_batchedUpdates 发挥作用的地方。它迫使 React 将多个状态更新分组到单个渲染中,即使在事件驱动的上下文之外也是如此,从而最大限度地减少重新渲染并提高性能。

例子:

没有unstable_batchedUpdates:

inc()  // triggers one render
inc()  // triggers another render

使用unstable_batchedUpdates:

ReactDOM.unstable_batchedUpdates(() => {
  inc()  // triggers only one render for both updates
  inc()
})

该方法被标记为“不稳定”,因为它不是 React 官方公共 API 的一部分,但它仍然在社区中广泛用于性能优化。未来它可能会变得更加稳定或集成为 React 新的并发渲染功能的一部分。

有趣的事实:Zustand 的 4.5.5 版本使用版本 — 19.0.0-rc.0

ReactDOM.unstable_batchedUpdates in Zustand’s testcase.

为什么在 Zustand 中使用 ReactDOM.unstable_batchedUpdates?

Zustand 是一个轻量级状态管理库,可与 React 的组件生命周期配合使用。尽管 Zustand 可以有效地处理状态更新,但 React 的反应系统将在每次状态发生变化时触发渲染。在短时间内发生多次状态变化的场景下,使用ReactDOM.unstable_batchedUpdates可以防止多次重新渲染并批量更新,从而提供更流畅、更高效的用户体验。

在提供的测试用例中,在批量更新中调用 inc 两次可确保计数仅更新一次,从而比单独运行每个更新更高效。

关于我们:

在 Think Throo,我们的使命是教授开源项目中使用的高级代码库架构概念。

通过在 Next.js/React 中练习高级架构概念,提高您的编码技能,学习最佳实践并构建生产级项目。

我们是开源的 — https://github.com/thinkthroo/thinkthroo (请给我们一颗星!)

通过我们基于代码库架构的高级课程来提高您的团队技能。请通过 [email protected] 联系我们以了解更多信息!

参考:

  1. https://github.com/pmndrs/zustand/blob/v4.5.5/tests/basic.test.tsx#L175C7-L175C39

  2. https://dev.to/devmoustafa97/do-you-know-unstablebatchedupdates-in-react-enforce-batching-state-update-5cn2

  3. https://dev.to/jackbuchananconroy/react-18-what-s-changed-automatic-batching-13ec

  4. https://react.dev/blog/2022/03/08/react-18-upgrade-guide#automatic-batching

  5. https://github.com/pmndrs/zustand/blob/v4.5.5/package.json#L246C4-L247C32



版本声明 本文转载于:https://dev.to/thinkthroo/reactdomunstablebatchedupdates-in-zustands-testcase-4led?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 除了“if”语句之外:还有哪些地方可以在不进行强制转换的情况下使用具有显式“bool”转换的类型?
    除了“if”语句之外:还有哪些地方可以在不进行强制转换的情况下使用具有显式“bool”转换的类型?
    无需强制转换即可上下文转换为 bool您的类定义了对 bool 的显式转换,使您能够在条件语句中直接使用其实例“t”。然而,这种显式转换提出了一个问题:“t”在哪里可以在不进行强制转换的情况下用作 bool?上下文转换场景C 标准指定了四种值可以根据上下文转换为的主要场景bool:语句:if、whi...
    编程 发布于2024-11-09
  • 如何在 Go (Gorilla) 中向特定客户端发送有针对性的 Websocket 更新?
    如何在 Go (Gorilla) 中向特定客户端发送有针对性的 Websocket 更新?
    在 Go (Gorilla) 中向特定客户端发送 Websocket 更新尽管是 Go 新手,但您寻求有关实现 Websocket 通信的指导您的预输入项目。您已尝试利用 Gorilla 的 GitHub 存储库中的示例,但在理解如何识别特定客户端并针对 websocket 更新进行定位方面遇到了挑...
    编程 发布于2024-11-09
  • 大批
    大批
    方法是可以在对象上调用的 fns 数组是对象,因此它们在 JS 中也有方法。 slice(begin):将数组的一部分提取到新数组中,而不改变原始数组。 let arr = ['a','b','c','d','e']; // Usecase: Extract till index p...
    编程 发布于2024-11-09
  • 使用swoole作为基于ESP6的脚本可编程控制器的云端物联网网关框架
    使用swoole作为基于ESP6的脚本可编程控制器的云端物联网网关框架
    脚本可编程控制器的本地功能已经基本完成,开始实现远程相关功能。 远程系统整体架构如下: 使用ESP8266的SDK实现tcp服务器和tcp客户端。 在tcp服务器的基础上编写http协议解析代码,设计简单的http服务器,处理与浏览器的数据交互,包括内置网页的下载,并使用ajax技术获取状态并保存数...
    编程 发布于2024-11-09
  • Bootstrap 4 Beta 中的列偏移发生了什么?
    Bootstrap 4 Beta 中的列偏移发生了什么?
    Bootstrap 4 Beta:列偏移的删除和恢复Bootstrap 4 在其 Beta 1 版本中引入了重大更改柱子偏移了。然而,随着 Beta 2 的后续发布,这些变化已经逆转。从 offset-md-* 到 ml-auto在 Bootstrap 4 Beta 1 中, offset-md-*...
    编程 发布于2024-11-09
  • 如何防止 Pandas 在保存 CSV 时添加索引列?
    如何防止 Pandas 在保存 CSV 时添加索引列?
    避免使用 Pandas 保存的 CSV 中的索引列使用 Pandas 进行修改后保存 csv 文件时,默认行为是包含索引列。为了避免这种情况,可以在使用 to_csv() 方法时将索引参数设置为 False。为了详细说明,请考虑以下命令序列:pd.read_csv('C:/Path/to/file....
    编程 发布于2024-11-09
  • 如何修复 macOS 上 Django 中的“配置不正确:加载 MySQLdb 模块时出错”?
    如何修复 macOS 上 Django 中的“配置不正确:加载 MySQLdb 模块时出错”?
    MySQL配置不正确:相对路径的问题在Django中运行python manage.py runserver时,可能会遇到以下错误:ImproperlyConfigured: Error loading MySQLdb module: dlopen(/Library/Python/2.7/site-...
    编程 发布于2024-11-09
  • 为什么在 Java 的 Random 类中设置种子会返回相同的数字?
    为什么在 Java 的 Random 类中设置种子会返回相同的数字?
    Java随机数生成:为什么设置种子返回相同的数字?尽管将Random类的种子设置为特定值,但随机数生成器始终返回相同的数字。让我们探讨一下可能导致此问题的原因。了解 Random 类和种子初始化Java Random 类旨在生成伪随机数。默认情况下,它使用其内部时钟作为种子值,使其生成相对可预测的数...
    编程 发布于2024-11-09
  • 在 Go 中使用 WebSocket 进行实时通信
    在 Go 中使用 WebSocket 进行实时通信
    构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要一种比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSoc...
    编程 发布于2024-11-09
  • 如何克服使用反射设置结构体字段值时 SetCan() 总是返回 False 的问题?
    如何克服使用反射设置结构体字段值时 SetCan() 总是返回 False 的问题?
    使用结构体的 SetString 探索反射反射提供了动态操作 Go 结构的强大工具。在此示例中,我们在尝试使用反射设置结构体字段的值时遇到一个常见问题:CanSet() 始终返回 false。这种障碍阻止了字段修改,使我们陷入困境。识别陷阱提供的代码片段突出显示了两个基本错误:传递值而不是指针: 按...
    编程 发布于2024-11-09
  • 为什么 MySQL 中带有子查询的“IN”查询很慢,如何提高性能?
    为什么 MySQL 中带有子查询的“IN”查询很慢,如何提高性能?
    MySQL 中带有子查询的缓慢“IN”查询当使用子查询时,使用“IN”运算符的 MySQL 查询可能会表现出显着的性能下降检索“IN”子句的值很复杂。在这种情况下,用显式值替换子查询结果会显着缩短执行时间。要了解此行为的原因,需要注意的是,每次评估“IN”查询时,MySQL 都会执行子查询。在提供的...
    编程 发布于2024-11-09
  • 如何使用WinAPI获取屏幕分辨率?
    如何使用WinAPI获取屏幕分辨率?
    使用 WinAPI 获取屏幕分辨率在 WinAPI 中,存在多个函数来确定当前屏幕分辨率。适当的选择取决于具体要求。检索显示尺寸主监视器:使用 GetSystemMetrics(SM_CXSCREEN) 和 GetSystemMetrics( SM_CYSCREEN) 获取主显示器的宽度和高度。所有...
    编程 发布于2024-11-09
  • 如何修复通过 Gmail REST API 发送电子邮件时出现的“400 错误请求 + 失败前提条件”错误?
    如何修复通过 Gmail REST API 发送电子邮件时出现的“400 错误请求 + 失败前提条件”错误?
    Gmail REST API:解决“400 Bad Request Failed Precondition”错误尝试使用 Gmail REST API 与服务器发送电子邮件时 -到服务器授权时,您可能会遇到一条错误消息,指出“400 Bad Request Failed Precondition”。...
    编程 发布于2024-11-09
  • 如何使用 LOAD XML 和 XML_LOAD() 将缺少 ID 列的 XML 文件导入 MySQL?
    如何使用 LOAD XML 和 XML_LOAD() 将缺少 ID 列的 XML 文件导入 MySQL?
    使用 XML_LOAD() 函数将 XML 文件导入 MySQL在这种情况下,您在尝试使用以下命令将 XML 文件导入 MySQL 数据库表时遇到错误加载 XML 命令。出现此问题的原因是表中的字段数与 XML 文件中的值不匹配,并且表中多了一个自动递增 id 字段。要解决此错误,您可以指定要使用 ...
    编程 发布于2024-11-09
  • C++ 对象的内存是如何组织的?
    C++ 对象的内存是如何组织的?
    C 对象的内存布局动态转换和重新解释操作通常涉及操作对象内存指针。让我们深入研究 C 如何在内存中组织对象,以便更好地理解这些操作。根据 C 标准,类或结构中非静态数据成员的内存布局主要由它们的声明顺序决定。具有相同访问说明符的成员按其声明的顺序排序。除了成员变量之外,对象还为以下对象分配空间:成员...
    编程 发布于2024-11-09

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3