Material UI DataGrid自定义复选框:加载时显示状态并保留选中功能
解决Material UI DataGrid加载时替换复选框为加载状态并保留选中功能的方案
方法一:自定义选择列+复用DataGrid原生选中逻辑
关闭DataGrid默认的复选框选择,自定义一列来实现“加载时显示加载组件,完成后显示复选框”的效果,同时通过apiRef调用DataGrid内置的选中方法,完全保留原生选择功能。
import { DataGrid, CircularProgress } from '@mui/x-data-grid'; import { useGridApiRef } from '@mui/x-data-grid'; import { useState, useEffect } from 'react'; export default function LoadingAwareDataGrid() { const apiRef = useGridApiRef(); const [loading, setLoading] = useState(true); const [rows, setRows] = useState([]); // 模拟异步数据加载 useEffect(() => { setTimeout(() => { setRows([ { id: 1, name: 'John Doe', age: 35 }, { id: 2, name: 'Jane Smith', age: 28 }, { id: 3, name: 'Bob Brown', age: 42 }, ]); setLoading(false); }, 2000); }, []); // 自定义选择列配置 const selectionColumn = { field: 'selection', headerName: '', width: 50, renderCell: (params) => { if (loading) { return <CircularProgress size={20} />; } // 复用原生选中逻辑 return ( <input type="checkbox" checked={apiRef.current.isRowSelected(params.id)} onChange={() => apiRef.current.toggleRowSelection(params.id)} /> ); }, renderHeader: () => { if (loading) { return <CircularProgress size={20} />; } // 表头复选框同样处理 return ( <input type="checkbox" checked={apiRef.current.isAllRowsSelected()} onChange={() => apiRef.current.toggleAllRowsSelection()} /> ); }, }; const columns = [ selectionColumn, { field: 'name', headerName: 'Name', width: 150 }, { field: 'age', headerName: 'Age', width: 100 }, ]; return ( <div style={{ height: 400, width: '100%' }}> <DataGrid apiRef={apiRef} rows={rows} columns={columns} checkboxSelection={false} // 关闭默认复选框 onRowSelectionModelChange={(selectedIds) => { console.log('选中行ID列表:', selectedIds); // 这里可以直接拿到选中行的ID,做后续处理 }} /> </div> ); }
方法二:自定义BaseCheckbox组件并保留原生props
如果要沿用DataGrid默认的复选框列,直接替换BaseCheckbox组件即可,核心是传递所有原生props,确保原有选中逻辑不丢失,同时通过onRowSelectionModelChange直接获取选中行数据。
import { DataGrid, BaseCheckbox } from '@mui/x-data-grid'; import { CircularProgress } from '@mui/material'; import { useState, useEffect } from 'react'; export default function CustomCheckboxGrid() { const [loading, setLoading] = useState(true); const [rows, setRows] = useState([]); useEffect(() => { setTimeout(() => { setRows([ { id: 1, name: 'Alice', age: 30 }, { id: 2, name: 'Bob', age: 40 }, { id: 3, name: 'Charlie', age: 25 }, ]); setLoading(false); }, 2000); }, []); const columns = [ { field: 'name', headerName: 'Name', width: 150 }, { field: 'age', headerName: 'Age', width: 100 }, ]; return ( <div style={{ height: 400, width: '100%' }}> <DataGrid rows={rows} columns={columns} checkboxSelection components={{ BaseCheckbox: (props) => { if (loading) { return <CircularProgress size={20} />; } // 必须传递所有props,保留原生选中逻辑 return <BaseCheckbox {...props} />; }, }} onRowSelectionModelChange={(selectedIds) => { console.log('选中行ID:', selectedIds); // 如需获取完整行数据,可通过apiRef或直接从rows数组筛选 const selectedRows = rows.filter(row => selectedIds.includes(row.id)); console.log('选中行详情:', selectedRows); }} /> </div> ); }
关键注意点
- 自定义组件时必须传递所有原生props,尤其是
checked和onChange,否则会丢失选中状态同步逻辑 - 不要手动重写
onClick事件,直接使用DataGrid提供的onRowSelectionModelChange回调,能直接拿到选中行ID数组,无需自行解析点击事件 - 表头复选框的状态切换逻辑,通过
apiRef调用内置方法即可,无需手动实现全选/反选逻辑
内容的提问来源于stack exchange,提问作者vbotio
相关产品推荐
相关产品推荐

