MRT logoMaterial React Table

On This Page

    Migrating to Material React Table V2 from V1

    This should be an easy to moderate upgrade for most developers. The only breaking changes have to do with the removed tableInstanceRef, some renamed props/options, and new column sizing behaviors.

    Note: As of v2.12.0, the React and ReactDom peer dependencies have been moved back down to React v17 in order to help more people upgrade to MRT v2 without having to upgrade to React v18.

    New Feature Highlights

    1. New optional but recommended useMaterialReactTable hook that allows you to create the table instance in your own scope

    2. Greatly improved editing and new creating features

    3. New row pinning Features

    4. New column filtering 'popover' display mode to give a more "Excel-like" filtering experience

    5. New autocomplete, date, and date range filter variants

    6. New pagination UI options

    7. New alert banner UI options and overrides available

    8. New loading overlay UI

    9. Improved table head cell default styles

    10. Improved column sizing and layout modes for column resizing features

    11. All internal MRT components are now exported for custom headless use cases

    12. New optional createMRTColumnHelper utility function for better TValue/cell.getValue() type inference

    13. Many more features are compatible with virtualization

    See the full changelog for more details.

    Upgrade Dependencies

    Run this command to set the material-react-table dependency to the latest version in your package.json. This will not perform the full install yet.

    $ npx npm-check-updates -u material-react-table

    Your package.json should have "material-react-table": "^2.x.x" as a dependency.

    Then run the install command again. Either npm i, pnpm i, or yarn, etc. Or run the full command below to make sure all MUI dependencies are also upgraded or installed.

    $ npm i material-react-table @mui/material @mui/x-date-pickers @mui/icons-material @emotion/react @emotion/styled

    Breaking Changes

    • @mui/x-date-pickers v >=6.15.0 is now a required peer dependency. If not already installed from the previous step, install it with:

    $ npm i @mui/x-date-pickers
    • If you use the date picker features, you will also need to import the LocalizationProvider from @mui/x-date-pickers and wrap your app in it. Click here for more details.

    import { LocalizationProvider } from '@mui/x-date-pickers';
    import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
    export const App = () => {
    return (
    <ThemeProvider theme={createTheme({})}>
    {/* Add this if using date filter features */}
    <LocalizationProvider dateAdapter={AdapterDayjs}>
    <MyApp />
    </LocalizationProvider>
    </ThemeProvider>
    );
    };
    • MaterialReactTable is now a named export instead of a default export. Use curly braces to import it.

    - import MaterialReactTable from 'material-react-table'
    + import { MaterialReactTable, useMaterialReactTable } from 'material-react-table'
    • The tableInstanceRef prop has been replaced by the useMaterialReactTable hook, which is much easier to use. It is also recommended that all table options be passed to the new useMaterialReactTable hook instead as props to the <MaterialReactTable /> component. See below for more details.

    Renamed Props/Options

    • editingMode -> editDisplayMode

    • rowNumberMode -> rowNumberDisplayMode

    • enablePinning -> enableColumnPinning and enableRowPinning

    • virtualizerInstanceRef split into columnVirtualizerRef and rowVirtualizerRef

    • virtualizerProps split into columnVirtualizerOptions and rowVirtualizerOptions

    • columnVirtualizerProps -> columnVirtualizerOptions

    • rowVirtualizerProps -> rowVirtualizerOptions

    • muiTablePaginationProps -> muiPaginationProps

    • muiTableBodyCellCopyButtonProps -> muiCopyButtonProps

    • muiTableBodyCellEditTextFieldProps -> muiEditTextFieldProps

    • muiTableBodyCellSkeletonProps -> muiSkeletonProps

    • muiTableBodyRowDragHandleProps -> muiRowDragHandleProps

    • muiTableDetailPanelProps -> muiDetailPanelProps

    • muiTableHeadCellColumnActionsButtonProps -> muiColumnActionsButtonProps

    • muiTableHeadCellDragHandleProps -> muiColumnDragHandleProps

    • muiTableHeadCellFilterCheckboxProps -> muiFilterCheckboxProps

    • muiTableHeadCellFilterTextFieldProps -> muiFilterTextFieldProps

    • muiTableHeadCellFilterSliderProps -> muiFilterSliderProps

    • MRT_FilterFnsState -> MRT_ColumnFilterFns

    • MaterialReactTableProps -> MRT_TableOptions

    • MRT_FullScreenToggleButton => MRT_ToggleFullScreenButton

    useMaterialReactTable

    Passing all table options as props to <MaterialReactTable /> still works, but there now is an improved way to define table options with the useMaterialReactTable hook.

    For example, here is a classic example for how to use Material React Table in V1 (still works in v2):

    import { MaterialReactTable } from 'material-react-table';
    export const MyTableComponent = () => {
    // const tableInstanceRef = useRef(); //deprecated
    return (
    //Defining table options as props to <MaterialReactTable /> still works (as long as you don't also pass in a table prop)
    <MaterialReactTable
    columns={columns}
    data={data}
    enableRowSelection //table options as props
    // tableInstanceRef={tableInstanceRef} //deprecated
    />
    );
    };

    But you can now define all table options in the useMaterialReactTable.

    import {
    MaterialReactTable,
    useMaterialReactTable,
    } from 'material-react-table';
    export const MyTableComponent = () => {
    const table = useMaterialReactTable({
    columns,
    data,
    enableRowSelection: true, //table options as options to this hook
    });
    return (
    <MaterialReactTable
    table={table} //only pass in table instead of all table options
    />
    );
    };

    Why is useMaterialReactTable Better?

    There are a few reasons why having full access to the table instance is better than having MRT create it under the hood for you.

    1. There is no longer a need for a confusing tableInstanceRef prop that doesn't properly cause re-renders when the table instance changes. Now, any component that consumes the table instance will properly re-render when the table instance changes.

    2. It allows you to not have to use all of Material React Table's components. For example, if you only want to use the Table component with no TableContainer or Toolbars, you can simply import a different component from Material React Table.

    import { MRT_Table, useMaterialReactTable } from 'material-react-table';
    export const MyTableComponent = () => {
    const table = useMaterialReactTable({
    columns,
    data,
    enableRowSelection: true,
    });
    const selectedRows = table.getSelectedRowModel().rows;
    console.log(selectedRows);
    return (
    //this internal sub-component does not include the Paper, TableContainer, or Toolbars (lighter weight)
    <MRT_Table table={table} />
    );
    };

    Column Sizing and Layout Modes

    There are some new column sizing behaviors to be aware of in v2.

    In addition to the "semantic" and "grid" layoutModes, there is now a new "grid-no-grow" layoutMode that is automatically enabled by default when enableColumnResizing is true.

    This new layoutMode keeps columns in a fixed width, and columns will not grow to fill any remaining horizontal space. This is likely a very welcome change for most, but you can revert the behavior back to the old behavior by setting the layoutMode table option to "grid" or "semantic" manually.

    If you were previously trying to accomplish the same "grid-no-grow" by setting the flex-grow CSS to 0 in V1, it is recommended that you now remove that CSS in favor of simply using the new "grid-no-grow" layoutMode, which will also add an invisible "mrt-row-spacer" display column that makes the row borders look better.

    - muiTableHeadCellProps={{
    - sx: {
    - flex: '0 0 auto',
    - },
    - }}
    - muiTableBodyCellProps={{
    - sx: {
    - flex: '0 0 auto',
    - },
    - }}
    + layoutMode="grid-no-grow"

    Is anything missing from this v2 migration guide? Make a PR or join the Discord to discuss.