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

React Material-UI DataGrid:如何阻止单元格聚焦/失焦触发renderCell?

解决React Material-UI DataGrid中renderCell因单元格聚焦/失焦重复执行的问题

当使用DataGrid的renderCell自定义单元格内容时,单元格聚焦或失焦会触发组件重渲染,导致renderCell内的逻辑重复执行——这是因为默认单元格组件会根据聚焦状态更新,进而重新调用renderCell。以下是两种有效的解决方法:

方法1:将单元格内容封装为纯组件(推荐)

把renderCell中的逻辑抽离成独立的纯组件,用React.memo包裹,让组件仅在props变化时重新渲染,避免聚焦状态切换带来的无意义执行。

import React from 'react';
import { DataGrid } from '@mui/x-data-grid';

// 封装纯组件,仅当value变化时才重新渲染
const IPCell = React.memo(({ value }) => {
  console.log("IP单元格逻辑执行 => ");
  return <span>{value}</span>;
});

// 列定义
const columns = [
  // 其他列...
  {
    field: "ip",
    headerName: "IP".toUpperCase(),
    renderCell: (params) => <IPCell value={params.value} />
  }
];

// 组件使用
export default function App() {
  const rows = [/* 你的数据行 */];
  return (
    <div style={{ height: 400, width: '100%' }}>
      <DataGrid rows={rows} columns={columns} />
    </div>
  );
}

方法2:使用useMemo缓存单元格内容

在renderCell内部用useMemo缓存返回的元素,仅依赖单元格的实际值,这样聚焦状态变化时不会触发逻辑重复执行。注意需确保renderCell所在的列定义位于React组件内部,避免hooks报错。

import React, { useMemo } from 'react';
import { DataGrid } from '@mui/x-data-grid';

export default function App() {
  const rows = [/* 你的数据行 */];
  const columns = [
    // 其他列...
    {
      field: "ip",
      headerName: "IP".toUpperCase(),
      renderCell: (params) => {
        const cellContent = useMemo(() => {
          console.log("IP单元格逻辑执行 => ");
          return <span>{params.value}</span>;
        }, [params.value]); // 仅当value变化时重新计算
        return cellContent;
      }
    }
  ];

  return (
    <div style={{ height: 400, width: '100%' }}>
      <DataGrid rows={rows} columns={columns} />
    </div>
  );
}

原理说明

DataGrid的单元格在聚焦时会添加额外的样式或状态,默认会触发整个单元格组件的重渲染。通过纯组件或useMemo,我们让单元格内容仅依赖业务数据(如params.value),忽略聚焦状态带来的组件更新,从而避免renderCell内的逻辑重复执行。

内容的提问来源于stack exchange,提问作者Yuniel Leal Yanes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 13:12:33