React组件测试已加act()仍报state更新需包裹在act中错误如何解决?
React测试act警告报错解决方案
报错根本原因
你手动包裹的act块只覆盖了点击事件的同步执行流程,fetchCityData的Promise回调属于微任务,会在当前act块执行完毕后才触发,此时回调内调用setPayload更新状态的逻辑没有被act包裹,因此触发了警告。
解决步骤
- 第一步:Mock异步请求方法
测试环境下不要调用真实后端接口,先Mock你的fetchCityData方法,让它返回固定的测试数据,示例如下:
// 替换为你实际的fetchCityData导入路径 jest.mock('./api', () => ({ fetchCityData: jest.fn(() => Promise.resolve({ location: { id: 1001, name: 'London' }, current: { temp_c: 18 } })) }))
- 第二步:重构测试代码,使用异步查询代替手动act
React Testing Library 提供的findBy*系列查询方法本身已经内置了act处理,会自动等待异步状态更新完成,不需要你手动包裹act,修改后的测试代码如下:
test('render weather into component', async () => { const { getByText, findByText } = render(<ForecastButtons city={'London'} />); // 点击触发请求 fireEvent.click(getByText('Today')) // 等待异步内容渲染完成 expect(await findByText('Current weather in London is 18 degrees')).toBeInTheDocument(); })
- 可选排查项:如果修改后还是出现警告,检查以下两点:
- 升级你的
@testing-library/react到v13及以上版本,旧版本对异步act的支持不完善 - 检查组件内是否有其他未处理的异步逻辑(比如定时器、延迟执行代码),如果有可以配合
jest.useFakeTimers()和act()手动处理
- 升级你的
内容的提问来源于stack exchange,提问作者Katharina Schreiber
相关产品推荐
相关产品推荐

