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

React测试报错:HomePage更新未包裹在act(...)中,求排查解决

解决React测试中异步状态更新引发的act警告

你的测试能通过但出现act警告,核心原因是组件useEffect里的异步状态更新(setItem)发生在act块之外:

  • 你手动用act包裹了render和fetch模拟,但fetch是异步操作,当Promise resolve时调用setItem,此时已经脱离了外层的act上下文,React检测到未被act包裹的状态更新,就会抛出警告。
  • 另外,React Testing Library的render方法本身已经自动用act处理了同步渲染逻辑,手动嵌套act反而会导致异步更新的状态无法被正确捕获。

修复步骤及代码示例

  1. 移除手动嵌套的act
    重构renderComponent,去掉多余的act包裹:
const renderComponent = () => {
  render(
    <MemoryRouter>
      <HomePage/>
      <ErrorPage/>
    </MemoryRouter>
  )
}
  1. 正确模拟fetch并处理异步逻辑
    注意response.json()实际返回的是Promise,之前的模拟不符合真实行为,同时用await waitFor确保异步状态更新完成后再断言:
it('Should render the Home page if the item is successfully retrieved', async () => {
  // 模拟fetch及异步json解析
  global.fetch = jest.fn(() =>
    Promise.resolve({
      json: () => Promise.resolve([{item: 'item1'}])
    })
  ) as jest.Mock

  renderComponent()

  // 等待状态更新和DOM渲染完成后断言
  await waitFor(() => {
    expect(screen.getByTestId('HomePage')).toBeInTheDocument()
  })
})
  1. 清理mock避免影响其他测试
    在测试块外添加清理逻辑,重置mock:
afterEach(() => {
  jest.restoreAllMocks()
})

为什么这样能解决问题

  • React Testing Library的render、waitFor等API已经内置了act处理,会自动捕获异步状态更新,不需要手动包裹act。
  • 修正json()的模拟为返回Promise,更贴近真实浏览器环境,避免潜在的异步时序问题。
  • await waitFor会等待所有异步操作完成、状态更新并渲染到DOM后再执行断言,确保整个流程都被act正确覆盖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:10:35