You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用testing-library/react-hooks测试时状态未更新问题排查

React状态未更新问题:自定义Hook与测试的修复方案

核心问题诊断

  • Hook代码bug:addToList函数里的setList写法错误,单个对象不能直接用数组扩展运算符展开,会导致数组结构异常,甚至阻塞状态更新流程
  • 测试时序问题:初始渲染时useEffect里的异步API请求还没完成,就直接调用addToList,此时初始的counter设置(从API返回的1)还没生效,后续更新逻辑被打乱

修复步骤

1. 修复自定义Hook的addToList函数

把错误的数组扩展写法改成正确的单个元素前置:

export const useCounter = (): UseCounterResult => {
  const session = useSession();
  const [list, setList] = useState<Customer[]>([]);
  const [counter, setCounter] = useState(0);
  const [limit, setLimit] = useState(10);
  useEffect(() => {
    (async () => {
      const response = await getApiClient(session).listCustomers();
      setList(response?.customers || []);
      setCounter(response.todayCount);
      setLimit(response.dailyLimit);
    })();
  }, [session]);

  function addToList(newItem: Customer) {
    // 修复:单个对象不需要扩展,直接放在数组首位
    setList(prevList => [newItem, ...prevList]);
    setCounter(prevCounter => prevCounter + 1);
  }

  return {counter, limit, list, addToList};
};

2. 修复单元测试的时序问题

必须等待初始useEffect的异步请求完成,确保初始状态设置好后,再执行addToList操作:

it.only("should add to list", async () => {
  // arrange
  (getApiClient as jest.Mock).mockReturnValue({
    listCustomers: async () => ({
      customers: [],
      todayCount: 1,
      dailyLimit: 5,
    }),
  });
  // act
  const { result, unmount, waitForNextUpdate } = renderHook(useCounter);
  
  // 等待初始useEffect的异步请求完成,状态更新为API返回的值
  await waitForNextUpdate();

  // 此时counter已经是1,再执行addToList
  act(() => {
    result.current.addToList({
      mobileNumber: "John",
      receiverName: "+61456789123",
    });
  });

  // 等待addToList触发的状态更新完成
  await waitForNextUpdate();

  // assert
  expect(result.current.counter).toBe(2);
  unmount();
});

补充说明

  • 使用函数式更新(setCounter(prev => prev +1))的写法是正确的,能确保基于最新状态更新,这个部分不需要修改
  • 如果测试中仍有问题,可以用waitFor替代waitForNextUpdate来等待断言条件满足,但优先保证时序逻辑正确

内容的提问来源于stack exchange,提问作者mehran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 17:17:46