DEV Community

Michael Turner
Michael Turner

Posted on

Getting Started with MUI X Data Grid in React: Building Your First Data Table

MUI X Data Grid is a powerful, feature-rich data grid component from Material-UI that provides Excel-like functionality for displaying and manipulating tabular data in React applications. It offers built-in features like sorting, filtering, pagination, and cell editing, making it perfect for building data-intensive interfaces. This guide walks through setting up and creating your first interactive data table using MUI X Data Grid with React, from installation to a working implementation. This is part 4 of a series on using MUI X Data Grid with React.

Prerequisites

Before you begin, make sure you have:

  • Node.js version 14.0 or higher installed
  • npm, yarn, or pnpm package manager
  • A React project (version 16.8 or higher) or create-react-app setup
  • Basic knowledge of React hooks (useState)
  • Material-UI core installed (required dependency)

Installation

First, install Material-UI core components and icons (required dependencies):

npm install @mui/material @mui/icons-material @emotion/react @emotion/styled
Enter fullscreen mode Exit fullscreen mode

Then install MUI X Data Grid:

npm install @mui/x-data-grid
Enter fullscreen mode Exit fullscreen mode

Or install everything with yarn:

yarn add @mui/material @mui/icons-material @emotion/react @emotion/styled @mui/x-data-grid
Enter fullscreen mode Exit fullscreen mode

Or with pnpm:

pnpm add @mui/material @mui/icons-material @emotion/react @emotion/styled @mui/x-data-grid
Enter fullscreen mode Exit fullscreen mode

After installation, your package.json should include:

{
  "dependencies": {
    "@mui/x-data-grid": "^6.0.0",
    "@mui/material": "^5.0.0",
    "@mui/icons-material": "^5.0.0",
    "@emotion/react": "^11.0.0",
    "@emotion/styled": "^11.0.0",
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

Project Setup

MUI X Data Grid uses Material-UI's theming system. Set up your app with the Material-UI theme provider. Update your main entry file:

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import App from './App';

const theme = createTheme();

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <ThemeProvider theme={theme}>
      <CssBaseline />
      <App />
    </ThemeProvider>
  </React.StrictMode>
);
Enter fullscreen mode Exit fullscreen mode

First Example / Basic Usage

Let's create a simple data grid component. Create a new file src/DataTable.jsx:

// src/DataTable.jsx
import React from 'react';
import { DataGrid } from '@mui/x-data-grid';

function DataTable() {
  // Define columns - structure of your table
  const columns = [
    { field: 'id', headerName: 'ID', width: 90 },
    { field: 'firstName', headerName: 'First name', width: 150 },
    { field: 'lastName', headerName: 'Last name', width: 150 },
    {
      field: 'age',
      headerName: 'Age',
      type: 'number',
      width: 110,
    },
    {
      field: 'email',
      headerName: 'Email',
      width: 200,
    },
  ];

  // Define rows - the data to display
  const rows = [
    { id: 1, lastName: 'Snow', firstName: 'Jon', age: 35, email: 'jon.snow@example.com' },
    { id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 42, email: 'cersei.lannister@example.com' },
    { id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 45, email: 'jaime.lannister@example.com' },
    { id: 4, lastName: 'Stark', firstName: 'Arya', age: 16, email: 'arya.stark@example.com' },
    { id: 5, lastName: 'Targaryen', firstName: 'Daenerys', age: null, email: 'daenerys.targaryen@example.com' },
    { id: 6, lastName: 'Melisandre', firstName: null, age: 150, email: 'melisandre@example.com' },
    { id: 7, lastName: 'Clifford', firstName: 'Ferrara', age: 44, email: 'ferrara.clifford@example.com' },
    { id: 8, lastName: 'Frances', firstName: 'Rossini', age: 36, email: 'rossini.frances@example.com' },
    { id: 9, lastName: 'Roxie', firstName: 'Harvey', age: 65, email: 'harvey.roxie@example.com' },
  ];

  return (
    <div style={{ height: 400, width: '100%' }}>
      <DataGrid
        rows={rows}
        columns={columns}
        pageSize={5}
        rowsPerPageOptions={[5]}
        checkboxSelection
        disableSelectionOnClick
      />
    </div>
  );
}

export default DataTable;
Enter fullscreen mode Exit fullscreen mode

Now, update your App.jsx to use the data table:

// src/App.jsx
import React from 'react';
import { Container, Typography, Box } from '@mui/material';
import DataTable from './DataTable';
import './App.css';

function App() {
  return (
    <Container maxWidth="lg">
      <Box sx={{ my: 4 }}>
        <Typography variant="h4" component="h1" gutterBottom>
          MUI X Data Grid Example
        </Typography>
        <DataTable />
      </Box>
    </Container>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

This creates a fully functional data grid with:

  • Sortable columns (click column headers)
  • Pagination (5 rows per page)
  • Row selection with checkboxes
  • Responsive layout

Understanding the Basics

MUI X Data Grid uses a column-based configuration where each column is defined with:

  • field: The property name in your row data objects
  • headerName: The text displayed in the column header
  • width: Column width in pixels
  • type: Data type ('string', 'number', 'date', etc.)

The rows prop accepts an array of objects where each object represents a table row. Each object must have an id field that uniquely identifies the row.

Key props:

  • rows: Array of row data objects
  • columns: Array of column definition objects
  • pageSize: Number of rows per page
  • checkboxSelection: Enable row selection with checkboxes
  • disableSelectionOnClick: Prevent row selection when clicking cells

Here's a simpler example with just a few columns:

// src/SimpleTable.jsx
import React from 'react';
import { DataGrid } from '@mui/x-data-grid';

function SimpleTable() {
  const columns = [
    { field: 'id', headerName: 'ID', width: 70 },
    { field: 'name', headerName: 'Name', width: 200 },
    { field: 'value', headerName: 'Value', width: 130, type: 'number' },
  ];

  const rows = [
    { id: 1, name: 'Item 1', value: 100 },
    { id: 2, name: 'Item 2', value: 200 },
    { id: 3, name: 'Item 3', value: 300 },
  ];

  return (
    <div style={{ height: 300, width: '100%' }}>
      <DataGrid rows={rows} columns={columns} />
    </div>
  );
}

export default SimpleTable;
Enter fullscreen mode Exit fullscreen mode

Practical Example / Building Something Real

Let's build a product inventory table with more features:

// src/ProductInventory.jsx
import React, { useState } from 'react';
import { DataGrid } from '@mui/x-data-grid';
import { Box, Typography, Paper } from '@mui/material';

function ProductInventory() {
  const [selectionModel, setSelectionModel] = useState([]);

  const columns = [
    { field: 'id', headerName: 'ID', width: 70 },
    { 
      field: 'name', 
      headerName: 'Product Name', 
      width: 200,
      editable: true
    },
    { 
      field: 'category', 
      headerName: 'Category', 
      width: 150,
      editable: true
    },
    { 
      field: 'price', 
      headerName: 'Price', 
      type: 'number',
      width: 130,
      editable: true,
      valueFormatter: (params) => {
        return `$${params.value.toFixed(2)}`;
      }
    },
    { 
      field: 'stock', 
      headerName: 'Stock', 
      type: 'number',
      width: 100,
      editable: true,
      cellClassName: (params) => {
        if (params.value < 10) {
          return 'low-stock';
        }
        return '';
      }
    },
    { 
      field: 'status', 
      headerName: 'Status', 
      width: 120,
      renderCell: (params) => {
        const status = params.value;
        const color = status === 'Active' ? 'green' : 'gray';
        return (
          <span style={{ color, fontWeight: 'bold' }}>
            {status}
          </span>
        );
      }
    }
  ];

  const rows = [
    { id: 1, name: 'Laptop', category: 'Electronics', price: 999.99, stock: 15, status: 'Active' },
    { id: 2, name: 'Mouse', category: 'Electronics', price: 29.99, stock: 8, status: 'Active' },
    { id: 3, name: 'Keyboard', category: 'Electronics', price: 79.99, stock: 12, status: 'Active' },
    { id: 4, name: 'Monitor', category: 'Electronics', price: 299.99, stock: 5, status: 'Active' },
    { id: 5, name: 'Desk Chair', category: 'Furniture', price: 199.99, stock: 20, status: 'Active' },
    { id: 6, name: 'Desk', category: 'Furniture', price: 349.99, stock: 3, status: 'Active' },
    { id: 7, name: 'Lamp', category: 'Furniture', price: 49.99, stock: 25, status: 'Active' },
  ];

  const handleCellEditCommit = (params) => {
    console.log('Cell edited:', params);
    // Here you would typically update your data source
    // For example: updateProduct(params.id, params.field, params.value);
  };

  return (
    <Box sx={{ p: 3 }}>
      <Typography variant="h5" component="h2" gutterBottom>
        Product Inventory
      </Typography>
      <Typography variant="body2" color="text.secondary" gutterBottom>
        {selectionModel.length} product(s) selected
      </Typography>
      <Paper sx={{ height: 400, width: '100%' }}>
        <DataGrid
          rows={rows}
          columns={columns}
          pageSize={5}
          rowsPerPageOptions={[5, 10, 20]}
          checkboxSelection
          disableSelectionOnClick
          selectionModel={selectionModel}
          onSelectionModelChange={(newSelection) => {
            setSelectionModel(newSelection);
          }}
          onCellEditCommit={handleCellEditCommit}
          sx={{
            '& .low-stock': {
              backgroundColor: '#ffebee',
              color: '#c62828',
              fontWeight: 'bold',
            },
          }}
        />
      </Paper>
    </Box>
  );
}

export default ProductInventory;
Enter fullscreen mode Exit fullscreen mode

This example demonstrates:

  • Editable cells (double-click to edit)
  • Custom cell rendering for status
  • Conditional styling for low stock items
  • Row selection with state management
  • Value formatting for currency
  • Cell edit event handling

Common Issues / Troubleshooting

  1. Grid not rendering: Ensure you've wrapped your app with ThemeProvider from @mui/material/styles and imported the necessary Material-UI dependencies.

  2. Missing styles: Make sure you've installed @emotion/react and @emotion/styled as they're required for Material-UI styling.

  3. "id" field required: Each row object must have a unique id field. If your data uses a different identifier, map it to id before passing to the grid.

  4. Editable cells not working: Set editable: true in your column definitions and handle the onCellEditCommit event to persist changes.

  5. TypeScript errors: If using TypeScript, ensure you're using the correct types from @mui/x-data-grid for columns and rows.

Next Steps

Now that you have a basic understanding of MUI X Data Grid:

  • Learn about advanced features like filtering, sorting, and column resizing
  • Explore server-side pagination for large datasets
  • Implement custom cell renderers and editors
  • Add export functionality (CSV, Excel)
  • Discover row grouping and aggregation features
  • Check the official documentation: https://mui.com/x/react-data-grid/
  • Look for part 5 of this series for more advanced topics

Summary

You've successfully set up MUI X Data Grid in your React application and created your first interactive data table. The component provides a solid foundation for building data-rich interfaces with built-in features like sorting, filtering, pagination, and cell editing, all styled with Material-UI's design system.

Top comments (0)