跳到內容
+

從 v6 遷移至 v7

本指南說明從 v6 遷移至 v7 的樹狀檢視所需的變更。

簡介

這是將 @mui/x-tree-view 從 v6 升級到 v7 的參考指南。若要深入了解新主要版本中的變更,請查看關於 MUI X v7 發佈的部落格文章

開始使用新版本

package.json 中,將 Tree View 套件的版本變更為 ^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,僅針對 Tree View,或執行 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 CoalescingOptional Chaining

Webpack 4 不支援這些功能,因此如果您使用 Webpack 4,您將需要自行轉譯這些功能,或升級至 Webpack 5。

以下是如何在 Webpack 4 上使用 @babel/preset-env 預設集轉譯這些功能的範例

 // 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

Tree Item 使用的必要 nodeId 屬性已重新命名為 itemId,以保持一致性

 <TreeView>
-  <TreeItem label="Item 1" nodeId="one">
+  <TreeItem label="Item 1" itemId="one">
 </TreeView>

相同的變更已套用至 ContentComponent 屬性

 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

已從 Tree View 元件中移除 parentIcon 屬性。

如果您將圖示傳遞至您的 Tree View 元件,您可以將相同的圖示傳遞至此元件上的 collapseIconexpandIcon 插槽,以達到相同的行為

  <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 /> 元件上的插槽。

如果您將 TransitionComponentTransitionProps 傳遞至您的 <TreeItem /> 元件,則需要在這個元件上使用新的 groupTransition 插槽

 <SimpleTreeView>
   <TreeItem
     itemId="1"
     label="Item 1"
-    TransitionComponent={Fade}
-    TransitionProps={{ timeout: 600 }}
+    slots={{ groupTransition: Fade }}
+    slotProps={{ groupTransition: { timeout: 600 } }}
   />
 </SimpleTreeView>

重新命名 Tree Item 元件的 group 類別

<TreeItem /> 元件的 group 類別已重新命名為 groupTransition,以與其新的插槽名稱相符。

 const StyledTreeItem = styled(TreeItem)({
-  [`& .${treeItemClasses.group}`]: {
+  [`& .${treeItemClasses.groupTransition}`]: {
    marginLeft: 20,
  },
 });

✅ 重新命名 onNodeToggleexpandeddefaultExpanded

展開屬性已重新命名,以更好地描述其行為

舊名稱 新名稱
onNodeToggle onExpandedItemsChange
expanded expandedItems
defaultExpanded defaultExpandedItems
 <TreeView
-  onNodeToggle={handleExpansionChange}
+  onExpandedItemsChange={handleExpansionChange}

-  expanded={expandedItems}
+  expandedItems={expandedItems}

-  defaultExpanded={defaultExpandedItems}
+  defaultExpandedItems={defaultExpandedItems}
 />

✅ 重新命名 onNodeSelectselecteddefaultSelected

選取屬性已重新命名,以更好地描述其行為

舊名稱 新名稱
onNodeSelect onSelectedItemsChange
selected selectedItems
defaultSelected defaultSelectedItems
 <TreeView
-  onNodeSelect={handleSelectionChange}
+  onSelectedItemsChange={handleSelectionChange}

-  selected={selectedItems}
+  selectedItems={selectedItems}

-  defaultSelected={defaultSelectedItems}
+  defaultSelectedItems={defaultSelectedItems}
 />

將焦點放在 Tree Item 而不是 Tree View 上

焦點現在套用至 Tree Item 根元素,而不是 Tree View 根元素。

此變更將允許需要焦點放在 Tree Item 上的新功能,例如項目的拖放重新排序。它還解決了焦點管理方面的幾個問題,例如在呈現大量項目時無法捲動到焦點項目。

這將主要影響您如何編寫測試以與 Tree View 互動

例如,如果您使用 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 建立新的無頭版本的 Tree Item 元件。

-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}
 />