0Pricing
React Academy · 课时

Zustand DevTools 与 Store 测试

通过 devtools 中间件连接 Redux DevTools,并直接对 Store 操作进行单元测试。

Zustand DevTools 与 Store 测试 是 CoddyKit 上的免费 React Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。

欢迎

在本课中,您将把 Zustand store 连接到 Redux DevTools,以进行时间旅行调试,并直接为 store 操作编写单元测试。

devtools 中间件

使用 devtools 中间件包装 store,将其连接到 Redux DevTools 浏览器扩展。之后,您可以在 DevTools 时间线中检查每个操作和状态变化。
import { create } from 'zustand';
import { devtools } from 'zustand/middleware';

const useStore = create(
  devtools(
    (set) => ({
      count: 0,
      increment: () => set(s => ({ count: s.count + 1 }), false, 'increment'),
    }),
    { name: 'CounterStore' }
  )
);

DevTools 中的命名操作

使用 devtools 时,将操作名称作为 set() 的第三个参数传入。该标签会显示在 DevTools 时间线中,便于追踪发生了哪些变化。
set(s => ({ count: s.count + 1 }), false, 'counter/increment');
// Appears as 'counter/increment' in Redux DevTools

组合 persist 和 devtools

可以串联多个中间件。将 devtools 包装在 persist 内部,即可查看所有状态变化,包括存储重新水合产生的变化。
const useStore = create(
  devtools(
    persist(
      (set) => ({ /* ... */ }),
      { name: 'my-store' }
    ),
    { name: 'MyStore' }
  )
);

测试 Zustand store

Zustand store 是普通的 JavaScript 对象。您可以直接测试它们,而不必渲染任何 React 组件。请导入 store,并在测试中调用 getState() 和 setState()。
import { useCounterStore } from './store';

beforeEach(() => useCounterStore.setState({ count: 0 }));

test('increment increases count', () => {
  useCounterStore.getState().increment();
  expect(useCounterStore.getState().count).toBe(1);
});

在测试之间重置状态

在 beforeEach 中使用初始值调用 setState,以便在测试之间重置 store,避免测试用例之间发生状态泄漏。
const initialState = { count: 0, user: null };

beforeEach(() => {
  useMyStore.setState(initialState);
});

在组件测试中模拟 store

对于组件测试,请模拟 store 钩子,使其返回受控值。这样,您就可以在不执行实际 store 逻辑的情况下,测试组件在不同 store 状态下的渲染结果。
vi.mock('./useCounterStore', () => ({
  useCounterStore: vi.fn(() => ({ count: 5, increment: vi.fn() })),
}));

测试异步操作

在测试中模拟 fetch,并通过 getState() 调用异步操作。使用 await 等待异步操作完成,然后断言更新后的状态。
global.fetch = vi.fn().mockResolvedValue({
  json: () => Promise.resolve({ id: 1, name: 'Alice' }),
});

await useUserStore.getState().fetchUser(1);
expect(useUserStore.getState().user.name).toBe('Alice');

生产环境中的 DevTools 防护

请通过有条件地应用中间件,在生产环境中禁用 devtools。这样可以避免向用户暴露 store 结构。
const isDev = process.env.NODE_ENV === 'development';

const useStore = create(
  isDev ? devtools(storeCreator, { name: 'App' }) : storeCreator
);

日志记录中间件

您可以编写自定义日志记录中间件,将每次状态变化记录到控制台,这在无法安装浏览器扩展时很有用。
const log = (fn) => (set, get, api) => fn(
  (args, replace, name) => {
    console.log('action', name, args);
    set(args, replace, name);
  }, get, api
);

快速检查

如何在测试之间将 Zustand store 重置为初始状态?

回顾

添加 devtools 中间件,并为操作命名,以生成易读的 DevTools 时间线。使用 getState()/setState() 直接测试 store,而不渲染组件。在 beforeEach 中重置状态,以隔离测试。

课程完成

恭喜您!您已完成 **使用 Zustand 管理状态**。现在您可以创建 store、使用选择器、持久化状态、通过 DevTools 调试,并为 store 逻辑编写单元测试。

常见问题解答

「Zustand DevTools 与 Store 测试」课时是免费的吗?

是的 — 「Zustand DevTools 与 Store 测试」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。

「Zustand DevTools 与 Store 测试」这节课中我会学到什么?

通过 devtools 中间件连接 Redux DevTools,并直接对 Store 操作进行单元测试。 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 React Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「Zustand DevTools 与 Store 测试」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 React Academy 课中编写并运行代码吗?

能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 创建您的第一个 Zustand Store
  2. 选择器与避免不必要的重新渲染
  3. 使用持久化中间件保存状态
  4. Zustand DevTools 与 Store 测试
← 返回 React Academy