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

测试MUI X DataGrid时出现大量act警告的解决方案咨询

解决MUI X DataGrid测试时的act警告问题

问题描述

测试完整页面组件时,MUI X DataGrid输出大量act(...)相关警告,无法准确定位问题根源。排查后确认问题与组件中useEffect内的列宽调整操作(autosizeColumns)及自动列宽相关props(autosizeOnMount、autosizeOptions)有关——注释这些代码后测试错误消失。尝试用waitFor包裹render方法被IDE提示“避免在waitFor回调中使用副作用”,需寻求正确解决方式。

MUI版本:

  • @mui/material: ^5.15.21
  • @mui/x-data-grid: ^7.8.0

解决方案

方法1:使用findBy*查询自动等待异步更新

Testing Library的findBy*系列查询内置了waitFor逻辑,会自动等待组件完成所有异步状态更新,无需手动包裹,可直接避免act警告:

describe("OrderList", () => {
  it("renders table correctly", async () => {
    render(
      <Provider store={store}>
        <Suspense fallback={<Loader />}>
          <ThemeProvider theme={theme}>
            <BrowserRouter>
              <AuthProvider>
                <OrderList />
              </AuthProvider>
            </BrowserRouter>
          </ThemeProvider>
        </Suspense>
      </Provider>
    );

    // findByRole会自动等待表格渲染及后续异步更新完成
    const grid = await screen.findByRole("grid");
    expect(grid).toBeInTheDocument();

    screen.debug(undefined, 10000000);
  });
});

方法2:在组件中跳过测试环境的自动列宽操作

在组件的useEffect中判断环境,测试环境下直接跳过列宽调整逻辑,避免触发额外的状态更新:

// ContentTableBody组件中修改useEffect
useEffect(() => {
  // 测试环境下跳过自动列宽计算
  if (process.env.NODE_ENV === 'test') return;
  
  if (!isFetching) {
    apiRef.current.autosizeColumns({
      includeHeaders: true,
      includeOutliers: true,
    });
  }
}, [isFetching, apiRef]);

同时可关闭测试环境下的autosizeOnMount:

// 组件返回的DataGrid中修改props
<DataGrid
  autosizeOptions={{
    includeOutliers: true,
    includeHeaders: true,
  }}
  autosizeOnMount={process.env.NODE_ENV !== 'test'}
  // 其他原有props...
/>

方法3:用waitFor包裹断言而非render

如果需要保留自动列宽逻辑,可将断言逻辑放入waitFor中,而非包裹render,这样既符合IDE要求,又能等待异步更新完成:

describe("OrderList", () => {
  it("renders table correctly", async () => {
    render(
      <Provider store={store}>
        <Suspense fallback={<Loader />}>
          <ThemeProvider theme={theme}>
            <BrowserRouter>
              <AuthProvider>
                <OrderList />
              </AuthProvider>
            </BrowserRouter>
          </ThemeProvider>
        </Suspense>
      </Provider>
    );

    // 等待所有异步状态更新完成后再断言
    await waitFor(() => {
      expect(screen.getByRole("grid")).toBeInTheDocument();
    });

    screen.debug(undefined, 10000000);
  });
});

原因分析

警告的核心是测试中组件的异步状态更新未被act处理:DataGrid的自动列宽功能会在组件挂载/数据加载完成后触发列宽计算,进而更新组件状态。测试代码中直接使用getByRole会在这些异步更新完成前执行断言,导致React抛出“未用act包裹状态更新”的警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 19:30:53