菜单

createWithEqualityFn

相关源文件

createWithEqualityFn 是 Zustand 核心 API 的一个特殊变体,它创建了一个具有内置相等性检查功能的 React hook。该函数允许开发者创建可以优化组件重新渲染时机的 store,通过提供自定义的相等性函数来进行状态比较。

有关不带相等性检查的标准 store 创建函数的信息,请参阅 create

1. 概述

createWithEqualityFn 通过允许您指定一个自定义相等性函数来扩展 Zustand 的基本 store 创建功能,该函数决定何时应发生重新渲染。当组件使用此 store 选择一部分状态时,相等性函数会决定新状态是否与先前状态“相等”,从而可能避免不必要的重新渲染。

来源: src/traditional.ts57-90 docs/apis/create-with-equality-fn.md7-14

2. API 参考

2.1 函数签名

该函数接受两个参数

  • stateCreatorFn: 一个接收 setgetstore 参数并返回初始状态(包含任何 action)的函数。
  • equalityFn: (可选) 一个用于比较前一个和下一个状态切片以确定相等性的函数。

返回值是一个 React hook,可以直接在组件中使用,并附带 Zustand store API 的实用方法。

来源: src/traditional.ts57-66 docs/apis/create-with-equality-fn.md34-37

2.2 返回值

createWithEqualityFn 返回的 hook 具有以下行为:

  1. 不带参数调用时,它返回整个 store 状态。
  2. 带选择器函数调用时,它返回状态中被选中的部分。
  3. 同时带选择器和相等性函数调用时,它使用提供的相等性函数进行该特定选择。

hook 还附带了所有 Zustand store API 方法: getState()setState()subscribe()getInitialState()

来源: src/traditional.ts49-55 docs/apis/create-with-equality-fn.md50-55

3. createWithEqualityFn 如何工作

createWithEqualityFn 的内部实现包含几个关键方面:

来源: src/traditional.ts68-82

  1. createWithEqualityFn 首先使用 Zustand 的核心 createStore 函数创建一个 vanilla store。
  2. 然后,它创建一个 hook 函数,该函数在内部使用 useStoreWithEqualityFn,而 useStoreWithEqualityFn 本身是 React 的 useSyncExternalStore 的包装器。
  3. 该 hook 接受一个可选的选择器函数和一个相等性函数(默认为创建 store 时提供的相等性函数)。
  4. Store API 的实用方法会附加到 hook 函数上,使得可以直接从 hook 访问它们。

返回 hook 的关键实现位于 useStoreWithEqualityFn 函数中,该函数使用 React 的同步机制来高效地管理订阅和更新。

来源: src/traditional.ts23-47

4. 与标准 create 的区别

createWithEqualityFn 和标准的 create 函数的主要区别在于:

功能createcreateWithEqualityFn
相等性检查使用严格相等性 (Object.is)允许自定义相等性函数
重新渲染控制基础通过自定义相等性实现精细控制
实现使用 React.useSyncExternalStore使用 useSyncExternalStoreWithSelector
外部依赖传统版本需要 use-sync-external-store

来源: src/react.ts43-64 src/traditional.ts57-90

5. 用法示例

5.1 创建一个使用浅比较的 Store

一个常见的用例是创建一个使用对象浅比较的 store,这对于具有顶层属性的状态对象更有效。

来源: docs/apis/create-with-equality-fn.md67-91

5.2 使用带有不同相等性函数的 Store

您还可以为不同的组件或状态选择使用不同的相等性函数。

来源: docs/apis/create-with-equality-fn.md151-160

6. 实现细节

了解其实现有助于有效使用 createWithEqualityFn

来源: src/traditional.ts68-82 src/traditional.ts33-47

实现依赖于以下关键组件:

  1. createStore:Zustand 的核心 vanilla store 创建器。
  2. useSyncExternalStoreWithSelector:由 'use-sync-external-store' 包提供。
  3. useStoreWithEqualityFn:useSyncExternalStoreWithSelector 的包装器,接受 store、选择器和相等性函数。

当组件重新渲染时,hook 会根据比较先前和当前选定状态时相等性函数的结果来决定是否触发另一次渲染。

7. 最佳实践

为了有效地使用 createWithEqualityFn

  1. 选择正确的相等性函数:

    • 对于属性结构简单的对象,使用 shallow
    • 对于复杂数据结构或特定比较需求,使用自定义相等性函数。
  2. 注意相等性函数的性能:

    • 相等性函数在每次状态更改时都会运行。
    • 复杂的相等性函数可能会抵消性能优势。
  3. 优先使用细粒度的选择器:

    • 在组件中只选择所需的数据。
    • 较小的状态切片使相等性检查更有效。

来源: docs/apis/create-with-equality-fn.md448-606

8. 故障排除

8.1 状态更新未触发重新渲染

如果状态更新没有导致重新渲染:

  1. 检查您的相等性函数是否可能错误地为不同状态返回 true
  2. 确保您是不可变地更新状态(创建新对象而不是进行变异)。
  3. 验证选择器是否选择了正在更改的状态部分。

来源: docs/apis/create-with-equality-fn.md520-524 docs/apis/create-with-equality-fn.md574-585

8.2 缺少依赖

如果您正在使用传统版本并遇到错误:

Error: Cannot find module 'use-sync-external-store/shim/with-selector'

您需要安装依赖项:

npm install use-sync-external-store

来源: docs/apis/create-with-equality-fn.md11-13

createWithEqualityFn 是 Zustand 中一系列相关 API 的一部分。

  • create:标准 store 创建,不带相等性检查。
  • useStore:用于在 React 中使用 vanilla store 的 hook。
  • useStoreWithEqualityFn:用于 vanilla store 的带相等性检查的 hook。
  • shallow:用于浅比较的实用工具。
  • useShallow:用于创建带浅比较的选择器的 hook。

来源: src/traditional.ts23-47 src/react/shallow.ts4-12