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

React Testing Library中使用异步user event出现ACT警告如何解决?

解决React测试中的ACT警告问题

问题原因

你遇到的ACT警告,核心原因是测试中使用了旧的DOM元素引用,没有等待组件更新后获取最新的DOM节点。虽然你的组件没有异步逻辑,但React状态更新会触发重新渲染,你提前保存的boardChildren数组里的元素是渲染初期的旧节点,点击后组件重新渲染,旧节点被替换,此时断言旧节点会导致React无法确认所有更新已完成,从而抛出ACT警告。

解决方案

修改测试代码,避免提前保存DOM元素引用,每次操作或断言前都重新从DOM中查询最新的元素;或者使用waitFor确保断言在组件更新完成后执行。

方案1:每次操作/断言前重新查询DOM

test("when user clicks second time, the clicked element gets 'circle' class", async () => {
  render(<Board />);

  // 第一次点击:获取最新的子元素
  await user.click(screen.getAllByTestId("board-child")[0]);
  // 第二次点击:重新获取最新的子元素
  await user.click(screen.getAllByTestId("board-child")[1]);
  // 断言:再次获取最新的目标元素
  expect(screen.getAllByTestId("board-child")[1]).toHaveClass("circle");
});

方案2:使用waitFor等待更新完成

import { waitFor } from '@testing-library/react';

test("when user clicks second time, the clicked element gets 'circle' class", async () => {
  render(<Board />);

  await user.click(screen.getAllByTestId("board-child")[0]);
  await user.click(screen.getAllByTestId("board-child")[1]);
  
  // 等待组件更新完成后再执行断言
  await waitFor(() => {
    expect(screen.getAllByTestId("board-child")[1]).toHaveClass("circle");
  });
});

额外优化建议

你的组件中handleUserClick里使用了多个@ts-ignore,可以通过类型断言消除类型错误,比如:

const handleUserClick = (e: React.MouseEvent<HTMLDivElement>) => {
  const target = e.target as HTMLDivElement;
  const index = Number(target.dataset.number);
  if (isNaN(index) || board[index] !== null) return;

  setBoard(p => p.map((el, i) => i === index ? currentSign : el));
  setCurrentSign(p => p === "cross" ? "circle" : "cross");
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 04:35:06