从 v6 迁移到 v7
本指南介绍了将树形视图从 v6 迁移到 v7 所需的更改。
简介
这是将 @mui/x-tree-view
从 v6 升级到 v7 的参考指南。要了解有关新主要版本更改的更多信息,请查看 关于 MUI X v7 发布的博客文章。
开始使用新版本
在 package.json
中,将树形视图包的版本更改为 ^7.0.0
。
-"@mui/x-tree-view": "^6.0.0",
+"@mui/x-tree-view": "^7.0.0",
更新 @mui/material
包
为了可以选择使用来自 @mui/material
的最新 API,软件包的对等依赖版本已更新至 ^5.15.14
。这只是次要版本更改,因此不应引起任何重大更改。请将您的 @mui/material
包更新到此版本或更高版本。
运行代码转换
preset-safe
代码转换将自动调整您的大部分代码,以适应 v7 中的重大更改。您可以运行 v7.0.0/tree-view/preset-safe
仅针对树形视图,或运行 v7.0.0/preset-safe
以同时针对其他 MUI X 组件,如数据表格。
在选择 <path>
参数时,您可以针对特定文件、文件夹或整个代码库运行它。
// Tree View specific
npx @mui/x-codemod@latest v7.0.0/tree-view/preset-safe <path>
// Target other MUI X components as well
npx @mui/x-codemod@latest v7.0.0/preset-safe <path>
由 preset-safe
代码转换处理的重大更改在屏幕右侧的目录中或在其处理的具体点旁边用 ✅ 表情符号表示。
如果您已经应用了 v7.0.0/tree-view/preset-safe
(或 v7.0.0/preset-safe
) 代码转换,则您应该无需对这些项目采取任何进一步操作。如果重大更改的特定部分不是代码转换的一部分或需要一些手动工作,它将在每个部分的末尾列出。
所有其他更改必须手动处理。
重大更改
由于 v7
是一个主要版本,因此它包含影响公共 API 的更改。这些更改是为了保持一致性、提高稳定性和为新功能腾出空间而进行的。
删除旧版捆绑包
所有 MUI X 包中已删除对 IE 11 的支持。不再包含用于支持旧浏览器(如 IE 11)的 legacy
捆绑包。
放弃 Webpack 4 支持
放弃对旧浏览器的支持也意味着我们不再转换现代浏览器原生支持的某些功能 – 例如 Nullish Coalescing 和 Optional Chaining。
Webpack 4 不支持这些功能,因此如果您正在使用 Webpack 4,您将需要自己转换这些功能或升级到 Webpack 5。
以下是如何在 Webpack 4 上使用 @babel/preset-env
preset 转换这些功能的示例
// webpack.config.js
module.exports = (env) => ({
// ...
module: {
rules: [
{
test: /\.[jt]sx?$/,
- exclude: /node_modules/,
+ exclude: [
+ {
+ test: path.resolve(__dirname, 'node_modules'),
+ exclude: [path.resolve(__dirname, 'node_modules/@mui/x-tree-view')],
+ },
+ ],
},
],
},
});
✅ 将 nodeId
重命名为 itemId
为了保持一致性,树形项目使用的必需 nodeId
prop 已重命名为 itemId
<TreeView>
- <TreeItem label="Item 1" nodeId="one">
+ <TreeItem label="Item 1" itemId="one">
</TreeView>
相同的更改已应用于 ContentComponent
prop
const CustomContent = React.forwardRef((props, ref) => {
- const id = props.nodeId;
+ const id = props.itemId;
// Render some UI
});
function App() {
return (
<SimpleTreeView>
<TreeItem ContentComponent={CustomContent} />
</SimpleTreeView>
)
}
✅ 使用 Simple Tree View 而不是 Tree View
<TreeView />
组件已被弃用,将在下一个主要版本中删除。您可以开始用新的 <SimpleTreeView />
组件替换它,该组件具有完全相同的 API
-import { TreeView } from '@mui/x-tree-view';
+import { SimpleTreeView } from '@mui/x-tree-view';
-import { TreeView } from '@mui/x-tree-view/TreeView';
+import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView';
return (
- <TreeView>
+ <SimpleTreeView>
<TreeItem itemId="1" label="First item" />
- </TreeView>
+ </SimpleTreeView>
);
如果您正在使用主题增强,您还需要迁移它
const theme = createTheme({
components: {
- MuiTreeView: {
+ MuiSimpleTreeView: {
styleOverrides: {
root: {
opacity: 0.5,
},
},
},
},
});
如果您正在使用 treeViewClasses
对象,您可以将其替换为新的 simpleTreeViewClasses
对象
import { treeViewClasses } from '@mui/x-tree-view/TreeView';
import { simpleTreeViewClasses } from '@mui/x-tree-view/SimpleTreeView';
-const rootClass = treeViewClasses.root;
+const rootClass = simpleTreeViewClasses.root;
使用插槽定义项目图标
定义 expandIcon
用于展开项目子项的图标(在此项目折叠时呈现)现在在 <TreeView />
和 <TreeItem />
组件上都定义为插槽。
如果您正在使用来自 @mui/icons-material
的 ChevronRight
图标,您可以停止将其传递给您的组件,因为它现在是默认值
-import ChevronRightIcon from '@mui/icons-material/ChevronRight';
<SimpleTreeView
- defaultExpandIcon={<ChevronRightIcon />}
>
{items}
</SimpleTreeView>
如果您正在将另一个图标传递给您的 Tree View 组件,您需要在该组件上使用新的 expandIcon
插槽
<SimpleTreeView
- defaultExpandIcon={<MyCustomExpandIcon />}
+ slots={{ expandIcon: MyCustomExpandIcon }}
>
{items}
</SimpleTreeView>
如果您正在将另一个图标传递给您的 <TreeItem />
组件,您需要在该组件上使用新的 expandIcon
插槽
<SimpleTreeView>
<TreeItem
itemId="1"
label="Item 1"
- expandIcon={<MyCustomExpandIcon />}
+ slots={{ expandIcon: MyCustomExpandIcon }}
/>
</SimpleTreeView>
定义 collapseIcon
用于折叠项目子项的图标(在此项目展开时呈现)现在在 <TreeView />
和 <TreeItem />
组件上都定义为插槽。
如果您正在使用来自 @mui/icons-material
的 ExpandMore
图标,您可以停止将其传递给您的组件,因为它现在是默认值
- import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
<SimpleTreeView
- defaultCollapseIcon={<ExpandMoreIcon />}
>
{items}
</SimpleTreeView>
如果您正在将另一个图标传递给您的 Tree View 组件,您需要在该组件上使用新的 collapseIcon
插槽
<SimpleTreeView
- defaultCollapseIcon={<MyCustomCollapseIcon />}
+ slots={{ collapseIcon: MyCustomCollapseIcon }}
>
{items}
</SimpleTreeView>
如果您正在将另一个图标传递给您的 <TreeItem />
组件,您需要在该组件上使用新的 collapseIcon
插槽
<SimpleTreeView>
<TreeItem
itemId="1"
label="Item 1"
- collapseIcon={<MyCustomCollapseIcon />}
+ slots={{ collapseIcon: MyCustomCollapseIcon }}
/>
</SimpleTreeView>
替换 parentIcon
parentIcon
prop 已从 Tree View 组件中删除。
如果您正在将一个图标传递给您的 Tree View 组件,您可以通过将相同的图标传递给该组件上的 collapseIcon
和 expandIcon
插槽来实现相同的行为
<SimpleTreeView
- defaultParentIcon={<MyCustomParentIcon />}
+ slots={{ collapseIcon: MyCustomParentIcon, expandIcon: MyCustomParentIcon }}
>
{items}
</SimpleTreeView>
定义 endIcon
在没有子项的项目旁边呈现的图标现在在 <TreeView />
和 <TreeItem />
组件上都定义为插槽。
如果您正在将一个图标传递给您的 Tree View 组件,您需要在该组件上使用新的 endIcon
插槽
<SimpleTreeView
- defaultEndIcon={<MyCustomEndIcon />}
+ slots={{ endIcon: MyCustomEndIcon }}
>
{items}
</SimpleTreeView>
如果您正在将一个图标传递给您的 <TreeItem />
组件,您需要在该组件上使用新的 endIcon
插槽
<SimpleTreeView>
<TreeItem
itemId="1"
label="Item 1"
- endIcon={<MyCustomEndIcon />}
+ slots={{ endIcon: MyCustomEndIcon }}
/>
</SimpleTreeView>
定义 icon
在项目旁边呈现的图标现在在 <TreeItem />
组件上定义为插槽。
如果您正在将一个图标传递给您的 <TreeItem />
组件,您需要在该组件上使用新的 icon
插槽
<SimpleTreeView>
<TreeItem
itemId="1"
label="Item 1"
- icon={<MyCustomIcon />}
+ slots={{ icon: MyCustomIcon }}
/>
</SimpleTreeView>
✅ 使用插槽定义组过渡
用于动画项目子项的组件现在在 <TreeItem />
组件上定义为插槽。
如果您正在将 TransitionComponent
或 TransitionProps
传递给您的 <TreeItem />
组件,您需要在该组件上使用新的 groupTransition
插槽
<SimpleTreeView>
<TreeItem
itemId="1"
label="Item 1"
- TransitionComponent={Fade}
- TransitionProps={{ timeout: 600 }}
+ slots={{ groupTransition: Fade }}
+ slotProps={{ groupTransition: { timeout: 600 } }}
/>
</SimpleTreeView>
重命名树形项目组件的 group
类
<TreeItem />
组件的 group
类已重命名为 groupTransition
,以与其新的插槽名称匹配。
const StyledTreeItem = styled(TreeItem)({
- [`& .${treeItemClasses.group}`]: {
+ [`& .${treeItemClasses.groupTransition}`]: {
marginLeft: 20,
},
});
✅ 重命名 onNodeToggle
、expanded
和 defaultExpanded
扩展 props 已被重命名以更好地描述其行为
旧名称 | 新名称 |
---|---|
onNodeToggle |
onExpandedItemsChange |
expanded |
expandedItems |
defaultExpanded |
defaultExpandedItems |
<TreeView
- onNodeToggle={handleExpansionChange}
+ onExpandedItemsChange={handleExpansionChange}
- expanded={expandedItems}
+ expandedItems={expandedItems}
- defaultExpanded={defaultExpandedItems}
+ defaultExpandedItems={defaultExpandedItems}
/>
✅ 重命名 onNodeSelect
、selected
和 defaultSelected
选择 props 已被重命名以更好地描述其行为
旧名称 | 新名称 |
---|---|
onNodeSelect |
onSelectedItemsChange |
selected |
selectedItems |
defaultSelected |
defaultSelectedItems |
<TreeView
- onNodeSelect={handleSelectionChange}
+ onSelectedItemsChange={handleSelectionChange}
- selected={selectedItems}
+ selectedItems={selectedItems}
- defaultSelected={defaultSelectedItems}
+ defaultSelectedItems={defaultSelectedItems}
/>
聚焦树形项目而不是树形视图
焦点现在应用于树形项目根元素,而不是树形视图根元素。
此更改将允许需要焦点位于树形项目上的新功能,例如项目的拖放重新排序。它还解决了焦点管理的几个问题,例如当渲染大量项目时无法滚动到聚焦项目。
这主要会影响您编写测试以与树形视图交互的方式
例如,如果您正在使用 react-testing-library
编写测试,以下是更改可能的样子
it('test example on first item', () => {
const { getByRole } = render(
<SimpleTreeView>
<TreeItem itemId="one" id="one">One</TreeItem>
<TreeItem itemId="two" id="two">Two</TreeItem>
</SimpleTreeView>
);
// Set the focus to the item "One"
- const tree = getByRole('tree');
+ const treeItem = getByRole('treeitem', { name: 'One' });
act(() => {
- tree.focus();
+ treeItem.focus();
});
- fireEvent.keyDown(tree, { key: 'ArrowDown' });
+ fireEvent.keyDown(treeItem, { key: 'ArrowDown' });
// Check if the new focused item is "Two"
- expect(tree)to.have.attribute('aria-activedescendant', 'two');
+ expect(document.activeElement).to.have.attribute('id', 'two');
})
✅ 使用 useTreeItemState
而不是 useTreeItem
useTreeItem
hook 已重命名为 useTreeItemState
。这将有助于基于未来的 useTreeItem
hook 创建树形项目组件的新 headless 版本。
-import { TreeItem, useTreeItem } from '@mui/x-tree-view/TreeItem';
+import { TreeItem, useTreeItemState } from '@mui/x-tree-view/TreeItem';
const CustomContent = React.forwardRef((props, ref) => {
- const { disabled } = useTreeItem(props.itemId);
+ const { disabled } = useTreeItemState(props.itemId);
// Render some UI
});
function App() {
return (
<SimpleTreeView>
<TreeItem ContentComponent={CustomContent} />
</SimpleTreeView>
)
}
✅ 重命名 onNodeFocus
为了保持一致性,onNodeFocus
回调已重命名为 onItemFocus
<SimpleTreeView
- onNodeFocus={onNodeFocus}
+ onItemFocus={onItemFocus}
/>