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

测试触发async thunk的React组件时出现act警告的解决方案咨询

React组件测试中Dispatch异步Thunk的act警告问题

警告信息

console.error
  Warning: An update to App inside a test was not wrapped in act(...).
  
  When testing, code that causes React state updates should be wrapped into act(...):
  
  act(() => {
    /* fire events that update state */
  });
  /* assert on the output */
  
  This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
      at App (/home/karlosos/Dev/nokia/playground/testing-redux/src/App.tsx:6:34)
      at Provider (/home/karlosos/Dev/nokia/playground/testing-redux/node_modules/react-redux/lib/components/Provider.js:19:3)
      at Wrapper (/home/karlosos/Dev/nokia/playground/testing-redux/src/testUtils.tsx:11:22)

    at printWarning (node_modules/react-dom/cjs/react-dom.development.js:86:30)
    at error (node_modules/react-dom/cjs/react-dom.development.js:60:7)
    at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom.development.js:27589:9)
    at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom.development.js:25508:5)
    at forceStoreRerender (node_modules/react-dom/cjs/react-dom.development.js:16977:5)
    at Object.handleStoreChange [as callback] (node_modules/react-dom/cjs/react-dom.development.js:16953:7)
    at node_modules/react-redux/lib/utils/Subscription.js:23:20

问题场景

测试包含异步Thunk的React组件时,测试结束后组件仍会执行状态更新,触发上述act(...)警告。已知等待所有异步动作完成可以解决,但这会让测试混入无需验证的逻辑;也试过在测试末尾添加临时hack代码消除警告,但不想逐个修改所有测试用例,寻求更优的批量/全局解决方案。

示例代码

测试用例

test('WHEN component rendered THEN counter value is being loaded', () => {
  // WHEN
  renderWithProviders(<App />)

  // THEN
  expect(Api.getValue).toHaveBeenCalledTimes(1);
  const loadingSpinner = screen.getByTestId('loading-spinner');
  expect(loadingSpinner).toBeInTheDocument();

  // 测试结束后组件仍会执行后续操作
  // 具体是API返回数据后更新组件显示
});

异步Thunk

export const fetchCounterValue = (): AppThunk => async (dispatch, getState) => {
  if (getState().counter.fetchValueStatus === "loading") {
    return;
  }

  dispatch(fetchValueStart());
  try {
    const result = await Api.getValue();
    dispatch(fetchValueSuccess(result));
  } catch (e) {
    dispatch(fetchValueError('Could not fetch the data'));
  }
};

已尝试的临时方案

在测试末尾添加以下代码可以消除警告,但属于临时hack:

await waitFor(() => new Promise(res => setTimeout(res, 0)));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 18:05:23