传递title给DataGridPro自定义Toolbar引发重渲染失焦,求解决方案
解决Material UI DataGridPro自定义Toolbar传title导致重渲染失焦的问题
问题根源
你遇到的问题本质是自定义Toolbar组件未做记忆化处理,当父组件传递的title prop每次渲染时被重新创建(哪怕值相同),会触发Toolbar的全量重渲染,导致QuickFilter这类输入组件丢失焦点。
可行解决方案
1. 用React.memo包裹自定义Toolbar
给你的TableToolbar组件套一层React.memo,让它只在props浅比较变化时才重渲染。如果title是固定字符串或引用稳定的值,这招直接见效:
import React from 'react'; import { GridToolbarQuickFilter, GridToolbarExport } from '@mui/x-data-grid-pro'; // 用React.memo包裹组件,实现浅比较缓存 const TableToolbar = React.memo(({ title }) => { return ( <div style={{ display: 'flex', gap: '16px', padding: '8px' }}> <GridToolbarQuickFilter /> <GridToolbarExport csvOptions={{ title: `${title}_导出数据` }} /> </div> ); }); // 在DataGridPro中使用 <DataGridPro components={{ Toolbar: TableToolbar }} componentsProps={{ toolbar: { title: '用户列表' } // 稳定值不会触发重渲染 }} // 其他配置项... />
如果title是动态生成的(比如来自父组件state/props),记得用useMemo稳定它的引用:
// 父组件中 const ParentComponent = () => { // 用useMemo缓存动态title,避免每次渲染生成新字符串引用 const tableTitle = React.useMemo(() => `用户列表_${new Date().getMonth() + 1}月`, []); return ( <DataGridPro components={{ Toolbar: TableToolbar }} componentsProps={{ toolbar: { title: tableTitle } }} /> ); };
2. 通过DataGrid上下文获取title(无需显式传prop)
如果不想显式传递title,可以把表格名称放到DataGrid的localeText里,让Toolbar直接读取:
// 父组件配置localeText <DataGridPro localeText={{ toolbarExport: `导出${tableTitle}数据`, // 其他本地化配置... }} components={{ Toolbar: TableToolbar }} // 其他配置项... /> // 自定义Toolbar中通过useGridLocaleText获取 const TableToolbar = () => { const localeText = useGridLocaleText(); // 从本地化文本中解析出title const exportTitle = localeText.toolbarExport.replace('导出', '').replace('数据', ''); return ( <div> <GridToolbarQuickFilter /> <GridToolbarExport csvOptions={{ title: `${exportTitle}_导出数据` }} /> </div> ); };
这种方式彻底避免了prop传递带来的重渲染触发点,适合需要多组件共享表格名称的场景。
3. 稳定所有Toolbar props的引用
如果Toolbar还接收其他props(比如回调函数、配置对象),记得用useCallback/useMemo稳定它们的引用,避免因其他props变化导致的不必要重渲染:
// 父组件中传递回调函数 const handleExport = React.useCallback(() => { // 导出逻辑 }, []); <DataGridPro componentsProps={{ toolbar: { title: tableTitle, onExport: handleExport // 用useCallback稳定引用 } }} />
内容的提问来源于stack exchange,提问作者asd
相关产品推荐
相关产品推荐

