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

在非全React的TypeScript应用中使用MUI X Data Grid API的优化咨询

关于在非React主导的TS应用中使用MUI X DataGrid的问题解答

1. 更优雅的实现方式

可以从以下几点优化,让代码更简洁可靠:

  • 将setApiRef的调用放到useEffect中,确保apiRef被DataGrid初始化完成后再传递,避免同步调用带来的空值问题
  • 移除Grid组件内部的React.StrictMode(它更适合包裹完整React应用,单个组件使用意义有限,还可能在开发环境触发重复渲染)
  • 直接在组件内部处理Promise的resolve逻辑,摆脱对外部setTimeout的依赖

优化后的代码示例:

import * as React from 'react';
import ReactDOM from 'react-dom/client';
import {StyledEngineProvider} from '@mui/material/styles';
import {DataGrid, useGridApiRef} from '@mui/x-data-grid';
import type {GridApi} from '@mui/x-data-grid';

export type ApiRefType = React.MutableRefObject<GridApi | undefined>;

type GridProps = {
  hideFooter: boolean;
  onApiReady: (ref: ApiRefType) => void;
};

const Grid = ({hideFooter, onApiReady}: GridProps): JSX.Element => {
  const apiRef = useGridApiRef();

  React.useEffect(() => {
    if (apiRef.current) {
      onApiReady(apiRef);
    }
  }, [apiRef, onApiReady]);

  return (
    <StyledEngineProvider injectFirst>
      <div style={{height: '100%', width: '100%'}}>
        <DataGrid 
          columns={[]} 
          rows={[]} 
          apiRef={apiRef}
          hideFooter={hideFooter}
        />
      </div>
    </StyledEngineProvider>
  );
};

export const renderGrid = (target: HTMLElement, hideFooter: boolean): Promise<ApiRefType> => {
  return new Promise((resolve) => {
    ReactDOM.createRoot(target).render(
      <Grid hideFooter={hideFooter} onApiReady={resolve} />
    );
  });
};

2. 为什么需要setTimeout才能获取GridApi

核心原因是React的渲染机制:

  • React的渲染是异步批量更新的:调用ReactDOM.createRoot(target).render()后,组件不会立即完成渲染和挂载,相关DOM更新、组件生命周期钩子会被放到当前事件循环的末尾执行。同步代码中直接获取apiRef时,DataGrid还未完成初始化,apiRef.current仍是空值。
  • setTimeout(fn, 0)会将回调放到下一个事件循环执行,此时React已完成组件渲染,DataGrid也已把初始化好的GridApi赋值给apiRef.current,因此能拿到有效值。

3. 不修改属性强制DataGrid刷新

完全可以实现,直接调用GridApi提供的refresh()方法即可:

// 假设已通过renderGrid拿到apiRef
apiRef.current?.refresh();

该方法会强制DataGrid重新渲染所有行和列,无需修改任何组件属性。如果需要更精细的刷新(比如仅刷新某一行/列),还可以使用apiRef.current?.updateRows()、apiRef.current?.updateColumns()等针对性API。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 04:17:19