跳到主要內容
+

從 v4 遷移到 v5

本指南說明從 v4 遷移資料網格到 v5 所需的變更。

簡介

本指南是將您的網站從 MUI X v4 升級到 v5 的參考指南。MUI X v5 完全相容於 Material UI v5 和 MUI System v5,並且可以與 Material UI v4 和 MUI System v4 一起使用,但需要一些額外步驟。大多數的重大變更都是 CSS 類別或變數的重新命名,以提高資料網格的一致性。

從 v4 遷移 MUI Core

將 MUI Core v4 與 v5 一起使用

將 Material UI v4 與 v5 一起使用可以透過以下步驟實現

  1. 首先,請確保您已安裝 Material UI v5。如果沒有,請依照這些指示進行安裝。
  2. 新增一個自訂的 createGenerateClassName 以停用 JSS 中全域類別名稱的產生。
import { createGenerateClassName } from '@material-ui/core/styles';

const generateClassName = createGenerateClassName({
  // By enabling this option, if you have non-MUI elements (for example `<div />`)
  // using MUI classes (for example `.MuiButton`) they will lose styles.
  // Make sure to convert them to use `styled()` or `<Box />` first.
  disableGlobal: true,
  // Class names will receive this seed to avoid name collisions.
  seed: 'mui-jss',
});
  1. 建立一個具有與 v4 主題相同自訂設定的 v5 主題。這必須完成,因為主題不會在不同的 Material UI 版本之間共享。
import { createMuiTheme as createThemeV4 } from '@material-ui/core/styles';
import { createTheme as createThemeV5 } from '@mui/material/styles';

const themeV4 = createThemeV4({
  palette: {
    primary: {
      main: '#2196f3',
    },
  },
});

const themeV5 = createThemeV5({
  palette: {
    primary: {
      main: themeV4.palette.primary.main,
    },
  },
});
  1. 將類別名稱產生器和 v5 主題應用於應用程式。
import * as React from 'react';
import { ThemeProvider as ThemeProviderV5 } from '@mui/material/styles';
import { ThemeProvider as ThemeProviderV4, StylesProvider } from '@material-ui/core/styles';

const generateClassName = createGenerateClassName({ ... });
const themeV4 = createThemeV4({ ... });
const themeV5 = createThemeV5({ ... });

export default function DataGridDemo() {
  return (
    <StylesProvider generateClassName={generateClassName}>
      <ThemeProviderV4 theme={themeV4}>
        <ThemeProviderV5 theme={themeV5}>
          {/* Your component tree. */}
        </ThemeProviderV5>
      </ThemeProviderV4>
    </StylesProvider>
  );
}

完成! 現在,您可以呈現任何依賴 Material UI v5 的相依性,而無需從 v4 升級,並且它們將無縫地並行運作。例如,以下互動式示範展示了這些步驟如何與資料網格結合在一起

遷移 MUI X

更新 MUI X 版本

若要使用 v5 版本的 MUI X,您首先需要更新到新的套件名稱

  • @material-ui/data-grid 現在是 @mui/x-data-grid (MIT)
  • @material-ui/x-grid 現在是 @mui/x-data-grid-pro (商業版)

CSS 類別

  • 某些 CSS 類別已移除或重新命名

    MUI X v4 類別 MUI X v5 類別
    .MuiDataGrid-window 已移除
    .MuiDataGrid-windowContainer 已移除
    .MuiDataGrid-viewport .MuiDataGrid-virtualScroller
    .MuiDataGrid-dataContainer .MuiDataGrid-virtualScrollerContent
    .MuiDataGrid-renderingZone .MuiDataGrid-virtualScrollerRenderZone
    .MuiDataGrid-gridMenuList .MuiDataGrid-menuList
    .MuiGridToolbarContainer-root .MuiDataGrid-toolbarContainer
    .MuiGridMenu-root .MuiDataGrid-menu
    .MuiDataGridColumnsPanel-root .MuiDataGrid-columnsPanel
    .MuiGridPanel-root .MuiDataGrid-panel
    .MuiGridPanelContent-root .MuiDataGrid-panelContent
    .MuiGridPanelFooter-root .MuiDataGrid-panelFooter
    .MuiDataGridPanelHeader-root .MuiDataGrid-panelHeader
    .MuiGridPanelWrapper-root .MuiDataGrid-panelWrapper
    .MuiGridFilterForm-root .MuiDataGrid-filterForm
    .MuiGridToolbarFilterButton-root .MuiDataGrid-toolbarFilterList

模組擴充

  • 模組擴充功能不再預設啟用。此變更是為了防止與同時使用 Data Grid 和 Data Grid Pro 的專案發生衝突。

    為了仍然能夠在主題層級進行覆寫,請將以下匯入新增到您的專案中

    +import type {} from '@mui/x-data-grid/themeAugmentation';
    +import type {} from '@mui/x-data-grid-pro/themeAugmentation';
    

虛擬化

  • onViewportRowsChange 屬性和 viewportRowsChange 事件已移除

    您可以使用 rowsScroll 事件的監聽器來取代它們

    const apiRef = useGridApiRef();
    const prevRenderContext = React.useRef(null);
    
    React.useEffect(() => {
      return apiRef.current.subscribeEvent('rowsScroll', ({ renderContext }) => {
        if (
          !prevRenderContext.current ||
          renderContext.firstRowIdx !== prevRenderContext.current.firstRowIndex ||
          renderContext.lastRowIdx !== prevRenderContext.current.lastRowIndex
        ) {
          prevRenderContext.current = renderContext;
          const params = {
            firstRowIndex: renderContext.firstRowIndex,
            lastRowIndex: renderContext.lastRowIndex,
          };
        }
      });
    }, [apiRef]);
    
    <DataGridPro apiRef={apiRef} />;
    

已移除的屬性

  • 為了提升效能,已從 GridCellGridRow 中移除某些事件監聽器和 DOM 屬性。

    以下屬性已移除。

    • onCellBlur
    • onCellOver
    • onCellOut
    • onCellEnter
    • onCellLeave
    • onRowOver
    • onRowOut
    • onRowEnter
    • onRowLeave

    如果您依賴它們,您可以使用 componentsProps.rowcomponentsProps.cell 將自訂屬性傳遞給列或儲存格。如需更多資訊,請查看此頁面。範例

    -<DataGrid onRowOver={handleRowOver} />;
    +<DataGrid
    +  componentsProps={{
    +    row: { onMouseOver: handleRowOver },
    +  }}
    +/>;
    

    data-rowindexdata-rowselected 屬性已從儲存格元素中移除。等效的屬性可以在列元素中找到。

    data-editable 屬性已從儲存格元素中移除。請使用 .MuiDataGrid-cell--editable CSS 類別。

    data-mode 屬性已從儲存格元素中移除。請使用 .MuiDataGrid-cell--editing CSS 類別。

狀態存取

  • 狀態直接存取不再被視為公開 API 的一部分。我們僅保證選擇器在次要版本之間繼續運作。我們建議您避免直接存取狀態子鍵,而是盡可能使用可用的選擇器或 apiRef 方法。您可以使用其對應的選擇器來取代以下狀態存取

    直接狀態存取 選擇器
    state.rows gridRowsStateSelector
    state.filter gridFilterStateSelector
    state.sorting gridSortingStateSelector
    state.editRows gridEditRowsStateSelector
    state.pagination gridPaginationSelector
    state.columns gridColumnsSelector
    state.columnMenu gridColumnMenuSelector
    state.focus gridFocusStateSelector
    state.tabIndex gridTabIndexStateSelector
    state.selection gridSelectionStateSelector
    state.preferencePanel gridPreferencePanelStateSelector
    state.density gridDensitySelector
    state.columnReorder gridColumnReorderSelector
    state.columnResize gridColumnResizeSelector
  • apiRef.current.getState 方法已移除。您可以直接透過 apiRef.current.state 存取狀態

    -const state = apiRef.current.getState();
    +const state = apiRef.current.state
    
     const filterModel = gridFilterModelSelector(state);
    
  • state 屬性運作不正確且已移除。您可以使用新的 initialState 屬性來取代。

    請注意,initialState 僅允許 preferencePanelfilter.filterModelsort.sortModel 鍵。若要完全控制狀態,請使用該功能模型的屬性和變更回呼 (例如 filterModelonFilterModelChange)。

     <DataGrid
    -  state={{
    +  initialState={{
         preferencePanel: {
           open: true,
           openedPanelValue: GridPreferencePanelsValue.filters,
         },
       }}
     />
    
  • 某些選擇器已重新命名以符合我們的命名慣例

    MUI X v4 選擇器 MUI X v5 選擇器
    unorderedGridRowIdsSelector gridRowIdsSelector
    sortingGridStateSelector gridSortingStateSelector
    sortedGridRowIdsSelector gridSortedRowIdsSelector
    filterGridStateSelector gridFilterModelSelector
    visibleSortedGridRowIdsSelector gridVisibleSortedRowIdsSelector
    visibleGridRowCountSelector gridVisibleRowCountSelector
    filterGridColumnLookupSelector gridFilterActiveItemsLookupSelector
    densitySelector gridDensitySelector
  • 某些選擇器已被移除/重新設計

    1. sortedGridRowsSelector 已移除。您可以使用 gridSortedRowEntriesSelector 來取代。

    傳回格式已變更

    -sortedGridRowsSelector: (state: GridState) => Map<GridRowId, GridRowModel>
    +gridSortedRowEntriesSelector: (state: GridState) => GridRowEntry[]
    

    如果您需要舊格式,您可以將選擇器傳回值轉換如下

    -const map = sortedGridRowsSelector(state);
    +const map = new Map(gridSortedRowEntriesSelector(state).map(row => [row.id, row.model]));
    
    1. filterGridItemsCounterSelector 已移除。您可以使用 gridFilterActiveItemsSelector
    -const filterCount = filterGridItemsCounterSelector(state);
    +const filterCount = gridFilterActiveItemsSelector(state).length;
    
    1. unorderedGridRowModelsSelector 已移除。您可以使用 apiRef.current.getRowModelsgridRowIdsSelectorgridRowsLookupSelector
    -const rowModels = unorderedGridRowModelsSelector(apiRef.current.state);
    
     // using the `apiRef`
    +const rowModels = apiRef.current.getRowModels();
    
     // using selectors
    +const allRows = gridRowIdsSelector(apiRef.current.state);
    +const idRowsLookup = gridRowsLookupSelector(apiRef.current.state);
    +const rowModels = new Map(allRows.map((id) => [id, idRowsLookup[id]]));
    
    1. visibleSortedGridRowsSelector 已移除。您可以使用 gridVisibleSortedRowEntriesSelector

    傳回格式已變更

    -visibleSortedGridRowsSelector: (state: GridState) => Map<GridRowId, GridRowModel>;
    +gridVisibleSortedRowEntriesSelector: (state: GridState) => GridRowEntry[];
    

    如果您需要舊格式,您可以將選擇器傳回值轉換如下

    -const map = visibleSortedGridRowsSelector(state);
    +const map = new Map(gridVisibleSortedRowEntriesSelector(state).map(row => [row.id, row.model]));
    
    1. visibleSortedGridRowsAsArraySelector 已移除。您可以使用 gridVisibleSortedRowEntriesSelector

    傳回格式已變更

    -visibleSortedGridRowsAsArraySelector: (state: GridState) => [GridRowId, GridRowData][];
    +gridVisibleSortedRowEntriesSelector: (state: GridState) => GridRowEntry[];
    

    如果您需要舊格式,您可以將選擇器傳回值轉換如下

    -const rows = visibleSortedGridRowsAsArraySelector(state);
    +const rows = gridVisibleSortedRowEntriesSelector(state).map(row => [row.id, row.model]);
    

apiRef 方法

  • 用於部分更新篩選器模型的 apiRef 方法已重新命名

    1. apiRef.current.applyFilterLinkOperator 已重新命名為 apiRef.current.setFilterLinkOperator
    2. apiRef.current.upsertFilter 已重新命名為 apiRef.current.upsertFilterItem
    3. apiRef.current.deleteFilter 已重新命名為 apiRef.current.deleteFilterItem
  • apiRef.current.selectRow 中的第三個引數現在已反轉,以與其他選取 API 保持一致。

    如果您傳遞 allowMultiple: true,您現在應該傳遞 resetSelection: false 或停止傳遞任何內容。

    如果您傳遞 allowMultiple: false 或未在 allowMultiple 上傳遞任何內容,您現在應該傳遞 resetSelection: true

    -selectRow: (id: GridRowId, isSelected?: boolean, allowMultiple?: boolean = false) => void;
    +selectRow: (id: GridRowId, isSelected?: boolean, resetSelection?: boolean = false) => void;
    

欄位

  • 傳遞給 valueFormatter 的參數已變更。

    您可以使用 api 取得遺失的參數。GridValueFormatterParams 介面現在具有以下簽章

    -export type GridValueFormatterParams = Omit<GridRenderCellParams, 'formattedValue' | 'isEditable'>;
    +export interface GridValueFormatterParams {
    +  /**
    +   * The column field of the cell that triggered the event.
    +   */
    +  field: string;
    +  /**
    +   * The cell value, but if the column has valueGetter, use getValue.
    +   */
    +  value: GridCellValue;
    +  /**
    +   * GridApi that lets you manipulate the Data Grid.
    +   */
    +  api: any;
    +}
    

其他匯出項目

  • gridCheckboxSelectionColDef 已重新命名為 GRID_CHECKBOX_SELECTION_COL_DEF

  • 個別字串常數已移除,改用單一 gridClasses 物件

    -const columnHeaderClass = GRID_COLUMN_HEADER_CSS_CLASS;
    +const columnHeaderClass = gridClasses.columnHeader;
    
    -const rowClass = GRID_ROW_CSS_CLASS;
    +const rowClass = gridClasses.row;
    
    -const cellClass = GRID_CELL_CSS_CLASS;
    +const cellClass = gridClasses.cell;
    
    -const columnSeparatorClass = GRID_COLUMN_HEADER_SEPARATOR_RESIZABLE_CSS_CLASS;
    +const columnSeparatorClass = gridClasses['columnSeparator--resizable'];
    
    -const columnHeaderTitleClass = GRID_COLUMN_HEADER_TITLE_CSS_CLASS;
    +const columnHeaderTitleClass = gridClasses.columnHeaderTitle;
    
    -const columnHeaderDropZoneClass = GRID_COLUMN_HEADER_DROP_ZONE_CSS_CLASS;
    +const columnHeaderDropZoneClass = gridClasses.columnHeaderDropZone;
    
    -const columnHeaderDraggingClass = GRID_COLUMN_HEADER_DRAGGING_CSS_CLASS;
    +const columnHeaderDraggingClass = gridClasses['columnHeader--dragging'];
    
  • 參考欄位類型的常數已移除。它們的值可以硬編碼。

    -const isColumnString = column.type === GRID_STRING_COLUMN_TYPE;
    +const isColumnString = col.type === 'string';
    
    -const isColumnNumber = col.type === GRID_NUMBER_COLUMN_TYPE;
    +const isColumnNumber = col.type === 'number';
    
    -const isColumnDate = col.type === GRID_DATE_COLUMN_TYPE;
    +const isColumnDate = col.type === 'date';
    
    -const isColumnDateTime = col.type === GRID_DATETIME_COLUMN_TYPE;
    +const isColumnDateTime = col.type === 'dateTime';
    
    -const isColumnBoolean = col.type === GRID_BOOLEAN_COLUMN_TYPE;
    +const isColumnBoolean = col.type === 'boolean';
    
  • useGridSlotComponentProps Hook 已移除。您可以使用以下 Hook 來存取相同的資料。

    -const { apiRef, state, rootElement, options } = useGridSlotComponentProps();
    +const apiRef = useGridApiContext();
    +const [state] = useGridState(apiRef);
    +const rootElement = apiRef.current.rootElementRef;
    +const rootProps = useGridRootProps(); // equivalent of `options`
    

從公開 API 中移除

我們從我們認為公開的 API 中移除了一些 API 方法/選擇器,方法是在它們前面加上 unstable_ 前綴。如果您願意,可以繼續使用這些方法,但它們將來可能會在沒有事先通知的情況下進行重大變更。

  1. apiRef.current.applyFilters 已重新命名為 apiRef.current.unstable_applyFilters
  2. gridContainerSizesSelector 已重新命名為 unstable_gridContainerSizesSelector
  3. gridViewportSizesSelector 已重新命名為 unstable_gridViewportSizesSelector
  4. gridScrollBarSizeSelector 已重新命名為 unstable_gridScrollBarSizeSelector