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

React测试中act已弃用却被Jest要求使用的解决方案咨询

React测试中act弃用警告与组件重渲染等待问题的解决方案

问题核心

你遇到的矛盾本质是:React 18+测试环境自动批处理状态更新,无需手动调用act,但旧代码依赖act强制等待状态更新,移除后因未正确等待异步用户操作导致测试失败;同时旧版act(callback)签名已被弃用,触发IDE警告。

解决方案

关键修改点

  1. 移除手动act调用:Testing Library的render、userEvent等API内部已自动用act包裹所有触发组件更新的操作,手动调用旧版act会触发弃用警告。
  2. 使用userEvent.setup()创建实例:这是@testing-library/user-event v13+的推荐用法,确保异步操作的生命周期被正确管理。
  3. 等待所有异步用户操作完成:每个userEvent的操作(如type、click)都是异步的,必须用await等待其完成,确保组件状态更新和重渲染结束后再执行断言。

修改后的测试代码

import '@testing-library/jest-dom'
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'

import ContactFormController from '.'

describe('Contact Form Controller tests', () => {
  it('should render loader and disable submit button on form submit', async () => {
    render(<ContactFormController />)

    const submitBtn = screen.getByTestId('contact-submit-button')
    const user = userEvent.setup()

    await user.type(screen.getByLabelText(/^First Name/i), 'Captain')
    await user.type(screen.getByLabelText(/^Last Name/i), 'Bob')
    await user.type(screen.getByLabelText(/^Email/i), 'captain@bob.com')
    await user.type(screen.getByPlaceholderText(/^Greetings/i), 'Captain Ahoy')
    await user.click(submitBtn)

    expect(screen.getByRole('alert')).toBeInTheDocument()
    expect(submitBtn).toBeDisabled()
  })
})

额外优化说明

  • 替换component.getBy*为screen.getBy*:这是Testing Library官方推荐的查询方式,无需保留render返回的组件实例,简化代码的同时符合测试最佳实践。
  • 若遇到异步操作(如表单提交后的API请求),可配合waitFor辅助函数等待断言条件满足,例如:
    await waitFor(() => {
      expect(screen.getByRole('alert')).toBeInTheDocument()
    })
    

原理说明

  • React 18+在测试环境中默认启用自动批处理,所有由用户交互、状态更新触发的组件更新会被自动批量处理,无需手动act包裹。
  • @testing-library/user-event v13+的setup()方法会创建一个绑定了测试上下文的用户事件实例,其返回的异步方法会自动等待组件更新完成,本质上已经封装了act的逻辑。
  • 之前移除act后测试失败,是因为未等待userEvent的异步操作完成,导致组件还未完成状态更新和重渲染就执行了断言,此时断言的目标元素或状态尚未出现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 10:23:12