为什么我在测试此钩子时会看到有关使用 act 的警告?

Jon*_*man 5 reactjs jestjs react-hooks-testing-library

当使用“@testing-library/react-hooks”中的 renderHook 时,我无法理解如何在没有以下警告的情况下为钩子编写测试。

“警告:测试中对 TestHook 的更新未包含在 act(...) 中。”

基本上,挂钩在状态中设置初始值useState,然后在useEffect挂钩内我异步执行一些操作,最终更新状态值。

import React from "react";

// fake request
const fetchData = () => Promise.resolve("data");

export const useGetData = () => {
  const initialData = { state: "loading" };
  const [data, setData] = React.useState(initialData);

  React.useEffect(() => {
    fetchData()
      .then(() => setData({ state: "loaded" }));
  }, []);

  return data;
};
Run Code Online (Sandbox Code Playgroud)

钩子总是简单地返回状态值..所以我编写了一个测试来断言它首先返回初始值并最终返回新的状态值。

import { renderHook } from "@testing-library/react-hooks";
import { useGetData } from "./useGetData";

describe("useGetData", async () => {
  it('Should initially return an object with state as "loading"', () => {
    const { result } = renderHook(() => useGetData());
    expect(result.current).toEqual({ state: "loading" });
  });

  it('Should eventually return an object with state as "loaded"', async () => {
    const { result, waitForNextUpdate } = renderHook(() => useGetData());
    await waitForNextUpdate();
    expect(result.current).toEqual({ state: "loaded" });
  });
});
Run Code Online (Sandbox Code Playgroud)

我创建了一个沙箱来复制此内容: https ://codesandbox.io/s/dazzling-faraday-ht4cd?file=/src/useGetData.test.ts

我已经研究了这个警告的含义以及行为是什么..但是对于这个特定的场景我不确定缺少什么。

小智 4

您可以通过执行以下操作来修复它:

await act(async () => {
  await waitForNextUpdate();
});
Run Code Online (Sandbox Code Playgroud)

您需要包装任何将由act函数更新状态的函数