如何避免MUI DataGrid在提交行时频繁重渲染?
MUI DataGrid 动态数据下避免频繁重渲染的方案
问题背景
MUI官方文档推荐的DataGrid实现方式如下:
const rows = [/* 行数据 */] <DataGrid rows={rows} {/* 其他属性 */} />
这种方式效率很高,DataGrid会自行处理内部状态,但仅适用于静态数据场景。对于需要通过网络动态获取行数据的情况,常规做法是用useState管理数据:
const [rows, setRows] = useState([]) /* 在异步请求逻辑中 */ // --begin-- let data = await /* 获取行数据的网络请求 */ setRows(data) // --end--
该方式能正常渲染数据,但每次提交行变更时必须调用setRows()同步UI,导致DataGrid频繁触发全量重渲染。
补充说明:若用let定义rows并在请求后直接修改,DataGrid无法检测到数据变更;而用useState管理时,全量替换数组会触发组件重渲染,影响性能。
解决方案
1. 利用DataGrid内置的行更新API
MUI DataGrid提供了受控模式下的局部更新方法,无需通过setRows全量替换数据,仅更新变更的行即可避免全量重渲染:
步骤1:获取DataGrid实例引用
使用useRef获取组件实例,用于调用内置API:
import { useRef } from 'react'; import { DataGrid } from '@mui/x-data-grid'; const MyDataGrid = () => { const gridRef = useRef(null); return ( <DataGrid ref={gridRef} rows={rows} columns={columns} {/* 其他配置:如编辑模式、行选择等 */} /> ); };
步骤2:局部更新行数据
当需要提交行变更时,调用DataGrid实例的updateRow(单条)或updateRows(批量)方法,仅传递修改后的行数据:
// 单条行更新示例 const handleRowSave = (updatedRow) => { // 直接调用DataGrid的内置方法更新指定行 gridRef.current.updateRow(updatedRow); }; // 批量行更新示例 const handleBulkSave = (updatedRowsArray) => { gridRef.current.updateRows(updatedRowsArray); };
这种方式只会更新目标行,DataGrid内部会高效处理状态变更,不会触发全组件重渲染。
2. 初始数据加载的优化
首次网络请求获取数据时,依然可以用useState初始化,但后续所有行变更都通过DataGrid的API处理:
const [rows, setRows] = useState([]); const gridRef = useRef(null); useEffect(() => { const fetchInitialData = async () => { const response = await /* 网络请求获取初始数据 */; setRows(response.data); }; fetchInitialData(); }, []); // 后续行变更仅使用gridRef的API,不再调用setRows
3. 父组件重渲染隔离(可选)
如果DataGrid的父组件会因其他状态变更触发重渲染,可以用React.memo包裹父组件,避免不必要的重渲染传递到DataGrid:
import { memo } from 'react'; const DataGridWrapper = memo(() => { // DataGrid相关逻辑和渲染 return <MyDataGrid />; });
内容的提问来源于stack exchange,提问作者Chukwujiobi Canon
相关产品推荐
相关产品推荐

