MUI X DataGrid useResizeContainer父容器高度为空报错求解
MUI X DataGrid useResizeContainer 空高度报错修复
问题表现
控制台抛出报错:useResizeContainer - The parent of the grid has an empty height
报错截图如下:
问题复现代码:
import * as React from "react"; import { DataGrid, GridColDef, GridValueGetterParams } from "@mui/x-data-grid"; import { Container, Tabs, Box, Tab } from "@mui/material"; interface TabPanelProps { children?: React.ReactNode; index: number; value: number; } function TabPanel(props: TabPanelProps) { const { children, value, index, ...other } = props; return ( <div role="tabpanel" hidden={value !== index} id={`simple-tabpanel-${index}`} aria-labelledby={`simple-tab-${index}`} {...other} > <Box sx={{ p: 3 }}> <div>{children}</div> </Box> </div> ); } function a11yProps(index: number) { return { id: `simple-tab-${index}`, "aria-controls": `simple-tabpanel-${index}` }; } export default function BasicTabs() { const [value, setValue] = React.useState(0); const handleChange = (event: React.SyntheticEvent, newValue: number) => { setValue(newValue); }; const columns: GridColDef[] = [ { field: "id", headerName: "ID", width: 90 }, { field: "firstName", headerName: "First name", width: 150, editable: true }, { field: "lastName", headerName: "Last name", width: 150, editable: true }, { field: "age", headerName: "Age", type: "number", width: 110, editable: true }, { field: "fullName", headerName: "Full name", description: "This column has a value getter and is not sortable.", sortable: false, width: 160, valueGetter: (params: GridValueGetterParams) => `${params.row.firstName || ""} ${params.row.lastName || ""}` } ]; const rows = [ { id: 1, lastName: "Snow", firstName: "Jon", age: 35 }, { id: 2, lastName: "Lannister", firstName: "Cersei", age: 42 }, { id: 3, lastName: "Lannister", firstName: "Jaime", age: 45 }, { id: 4, lastName: "Stark", firstName: "Arya", age: 16 }, { id: 5, lastName: "Targaryen", firstName: "Daenerys", age: null }, { id: 6, lastName: "Melisandre", firstName: null, age: 150 }, { id: 7, lastName: "Clifford", firstName: "Ferrara", age: 44 }, { id: 8, lastName: "Frances", firstName: "Rossini", age: 36 }, { id: 9, lastName: "Roxie", firstName: "Harvey", age: 65 } ] ; return ( <Box sx={{ width: "100%" }}> <Box sx={{ borderBottom: 1, borderColor: "divider" }}> <Tabs value={value} onChange={handleChange} aria-label="basic tabs example" > <Tab label="Item One" {...a11yProps(0)} /> <Tab label="Item Two" {...a11yProps(1)} /> <Tab label="Item Three" {...a11yProps(2)} /> </Tabs> </Box> <TabPanel value={value} index={0}> <Container> <DataGrid rows={rows} columns={columns} pageSize={5} rowsPerPageOptions={[5]} checkboxSelection disableSelectionOnClick /> </Container> </TabPanel> <TabPanel value={value} index={1}> Item Two </TabPanel> <TabPanel value={value} index={2}> Item Three </TabPanel> </Box> ); }
曾尝试将TabPanel的条件渲染逻辑从hidden控制改为直接渲染所有面板,报错依然存在。
报错根因
MUI X DataGrid默认使用useResizeContainer钩子监听父容器尺寸,要求父级容器必须存在可计算的非零高度,当前代码触发报错的核心原因有两点:
- TabPanel通过
hidden属性控制显隐,非激活状态的面板虽然保留在DOM树中,但浏览器会将其判定为不可见元素,高度计算值为0,DataGrid初始化时读取到父容器高度为0就会抛出警告 - 包裹DataGrid的
Container组件、内层嵌套div均未设置明确高度,即使在激活的标签页下,DataGrid首次渲染时也可能读取不到有效高度值
修复方案
根据业务场景选择以下任意一种方案即可:
方案1:直接给DataGrid设置固定高度(最快生效)
跳过父容器高度读取逻辑,直接给DataGrid本身设置高度,数值可根据业务需求调整:
<DataGrid rows={rows} columns={columns} pageSize={5} rowsPerPageOptions={[5]} checkboxSelection disableSelectionOnClick sx={{ height: 400 }} // 新增固定高度配置 />
方案2:修改TabPanel渲染逻辑+父容器设高
将TabPanel的hidden显隐逻辑改为条件渲染,只渲染当前激活的标签面板,避免非激活面板内的DataGrid在零高容器中初始化,同时给DataGrid的父容器设置明确高度:
- 修改TabPanel组件:
function TabPanel(props: TabPanelProps) { const { children, value, index, ...other } = props; // 非激活面板直接不挂载到DOM if (value !== index) return null; return ( <div role="tabpanel" id={`simple-tabpanel-${index}`} aria-labelledby={`simple-tab-${index}`} {...other} > <Box sx={{ p: 3 }}> <div>{children}</div> </Box> </div> ); }
- 给包裹DataGrid的Container设置高度:
<Container sx={{ height: 400 }}> <DataGrid rows={rows} columns={columns} pageSize={5} rowsPerPageOptions={[5]} checkboxSelection disableSelectionOnClick /> </Container>
方案3:开启DataGrid内容自适应高度
如果不需要固定高度、希望DataGrid根据行内容自动撑开,可以开启autoHeight属性,该模式下DataGrid不会读取父容器高度,会根据内容自动计算自身高度:
<DataGrid rows={rows} columns={columns} pageSize={5} rowsPerPageOptions={[5]} checkboxSelection disableSelectionOnClick autoHeight // 开启内容自适应高度 />
注意:开启
autoHeight后DataGrid不会出现内部滚动条,所有行会一次性渲染,数据量超过100条时不推荐使用,可能引发性能问题
内容的提问来源于stack exchange,提问作者razer
相关产品推荐
相关产品推荐

