MUI X v5 介绍
我们很高兴推出 MUI X v5.0.0!
MUI X 是我们的高级组件集合(包含 MIT 许可和商业许可的“Pro”功能)。目前,它仅包含一个数据网格。很快它将包含更多组件,如日期选择器和树状视图。此版本继续专注于使数据网格成为行业最佳。请继续阅读以了解更多信息!

此版本包含一些主要亮点
v5 的高层次目标
我们在两个领域开发不同的 React 组件:MUI Core 和 MUI X。这种方法认识到这两个产品中的组件解决的问题是不同的。成功的路径需要不同的策略。许多使用 MUI X 的开发人员也使用 Material UI、Base UI 和 MUI System,这些用户非常关心一致性(设计、文档、依赖项等)。
随着两个月前 MUI Core v5 的发布,MUI X 必须致力于提供有凝聚力的体验。这个新主要版本的首要目标是使 MUI X 提供与 MUI Core v5 的良好兼容性。
新的虚拟化引擎
DataGrid
和 DataGridPro
现在具有全新的虚拟化引擎!我们决定重写它,以解决社区提出的许多问题,并使其更容易发布影响行和列渲染的新功能。与以前版本相比,一个优势是我们现在使用原生滚动。这意味着滚动网格就像滚动网页一样,因此当滚动被覆盖时引起的任何抖动都消失了。
说到性能,我们遇到的主要问题之一是与垂直滚动相比,水平滚动滞后。经过调查,我们发现,尽管列是虚拟化的,但还是发生了许多不必要的渲染。这可以在下面的屏幕截图的顶部看到,其中比较了 v5.0.0-beta.4
(新虚拟化引擎之前的最后一个版本)和 v5.0.0
。在每个滚动事件中,它都会再次渲染,并且每个帧都需要很长时间才能绘制(有些甚至丢失了)。为了解决这些问题,我们采取了以下措施
- 避免在滚动期间渲染整个网格。
- 将正确的值传递给
key
属性,以确保 React 将重用现有的 DOM 节点。 - 减少附加到每个单元格的事件侦听器的数量。
- 增加在过度扫描中渲染的列数(为了使滚动更平滑而渲染的额外列)。
- 尽可能延迟新列的渲染。
这些更改的结果显示在比较的底部。与以前的虚拟化方法相比,在相同的时间内可以绘制的帧数显着增加。在我们的 基准测试 中,FPS(每秒帧数)平均从 22 增加到 42。每个帧渲染所需的时间(由每个块的宽度表示)减少了。
延迟重新渲染的想法也可以在块之间的大片空白中看到。每个空白都意味着重新渲染是不必要的,因为所需的列已经由过度扫描渲染。

一些提到的改进也应用于行,但是增益更微妙。除了更好的性能外,新的虚拟化引擎还带来了以下修复
- 水平和垂直滚动共享相同的逻辑。
- 更改渲染行时不再跳跃。
- 调用
apiRef.current.scrollToIndexes
无论单元格在哪里都有效。 - 改进了使用
disableVirtualization
时的支持。 - 修复了使用箭头键的键盘导航。
改进的状态管理
对状态管理进行了多项增强,以改善开发人员体验、性能以及执行顺序的一致性。
使用状态时改进的 DX
我们致力于简化状态结构和访问状态的工具。这些更改改进了使用 apiRef
方法时的开发人员体验
- 我们从公共 API 中删除了
state
结构。应始终通过apiRef
方法 (apiRef.current.getSelectedRows
) 或选择器 (selectedGridRowsSelector
) 访问状态中的数据。 - 我们重命名了大多数选择器以使其具有一致的命名约定,从而更容易推断其名称或推断目的。
- 我们重组了我们的状态,以便每个功能都有一个单独的子状态,并且功能钩子是唯一更新它的钩子(例如,
state.filter
仅由useGridFilter
钩子管理,该钩子公开了内部和第三方代码与此状态交互的方法)。
关于这个主题的工作尚未结束。我们正在进行或讨论一些开发,以改善开发人员在使用网格高级功能时的体验。以下是一些应在未来几个月内发布的功能
- 事件侦听器和发布者的严格类型。
- 事件侦听器的示例。
- 选择器的文档和示例。
- 添加导出和恢复网格状态某些部分的能力。
同步状态初始化
在以前的版本中,状态首先用默认值填充,然后在 useEffect
中,给定作为 props 提供的值(例如 props.pageSize
),或从 props 派生的值(从 props.rows
、props.sortModel
和 props.filterModel
派生的排序和过滤行)。这导致了使用无用数据的额外渲染,然后我们必须小心避免假数据和真实数据之间的闪烁。在 v5 中,状态在首次渲染期间同步初始化。
请注意,目前,来自受控 props 的状态更新仍然是异步的。如果您传递 props.pageSize
,我们将在 useEffect
中将其应用于状态,因此如果您在渲染后立即读取状态(例如在 useLayoutEffect
中),您仍然会看到旧版本。
简化的样式自定义
在以前的版本中,DataGrid
和 DataGridPro
组件的大多数内置 CSS 的 CSS 特异性 为 2。这意味着您通常添加的 CSS 的优先级低于数据网格的内置 CSS。这要求您打开开发人员工具,查看 DOM/CSSOM 树,以便使用正确的 CSS 选择器。使用 MUI X v5,我们将大多数内部 DataGrid
和 DataGridPro
组件的 CSS 特异性降低到 1。这使开发人员能够更轻松地更改网格组件的外观。
之前
const GridToolbarContainerStyled = styled(GridToolbarContainer)({
'&.MuiDataGrid-toolbarContainer': {
padding: 40,
},
});
function MyCustomToolbar() {
return (
<GridToolbarContainerStyled>My custom toolbar</GridToolbarContainerStyled>
);
}
export default function App() {
return (
<div style={{ height: 400, width: '100%' }}>
<DataGrid components={{ Toolbar: MyCustomToolbar }} />
</div>
);
}
之后
const GridToolbarContainerStyled = styled(GridToolbarContainer)({
padding: 40,
});
function MyCustomToolbar() {
return (
<GridToolbarContainerStyled>
My custom toolbar
</GridToolbarContainer>
);
};
export default function App() {
return (
<div style={{ height: 400, width: '100%' }}>
<DataGrid components={{ Toolbar: MyCustomToolbar }} />
</div>
);
}
自定义此内容的另一种方法是使用 sx
属性。
function MyCustomToolbar() {
// means "padding: theme.spacing(5)", NOT "5px"
return (
<GridToolbarContainer sx={{ p: 5 }}>My custom toolbar</GridToolbarContainer>
);
}
export default function App() {
return (
<div style={{ height: 400, width: '100%' }}>
<DataGrid components={{ Toolbar: MyCustomToolbar }} />
</div>
);
}
局限性
尽管这是一个明显的改进,但对于 DataGrid
和 DataGridPro
的某些部分,我们仍然必须保持 CSS 特异性为 2,特别是 GridColumnHeaderItem
、GridRow
和 GridCell
以及嵌套在其中的所有组件。这是由于与 Emotion 将样式注入到页面中的方式相关的性能影响,并且对于保持我们的虚拟化引擎的最佳性能是必要的。
v4 迁移
我们强烈建议您将 MUI X 迁移到 v5。在 MUI X v5 中,我们不仅添加了其他功能,还进行了重大的内部改进和性能优化,这些优化不会包含在 v4 中。所有新的 DataGrid
和 DataGridPro
功能将仅在 MUI X v5 中提供。
请查看 v4 迁移指南 以加速过渡。
下一步是什么?
更多激动人心的事物即将到来!我们在本季度的剩余时间里制定了宏伟的计划,涉及我们期望在 DataGrid
和 DataGridPro
组件中发布的功能。诸如 树状数据、列固定 和 可变行高 等功能是我们路线图的一部分。
公开路线图
作为一般规则,数据网格是任何处理大量数据的应用程序的基石。我们计划在必要时继续关注它,以交付大多数高级功能。
一旦我们扩大了团队并取得了足够的进展,我们将扩展到更多组件。
您可以在 GitHub 上查看我们的 公开路线图,以了解我们正在开发的功能、它们所处的阶段以及我们预计何时向您提供它们。
感谢
最后,再次感谢为 MUI X v5 做出贡献的每个人。我们对这个版本感到非常兴奋,我们将继续前进,交付下一代企业级 React UI 组件!这仅仅是开始。