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
Then install MUI X Data Grid:
npm install @mui/x-data-grid
Or install everything with yarn:
yarn add @mui/material @mui/icons-material @emotion/react @emotion/styled @mui/x-data-grid
Or with pnpm:
pnpm add @mui/material @mui/icons-material @emotion/react @emotion/styled @mui/x-data-grid
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"
}
}
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>
);
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;
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;
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;
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;
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
Grid not rendering: Ensure you've wrapped your app with
ThemeProviderfrom@mui/material/stylesand imported the necessary Material-UI dependencies.Missing styles: Make sure you've installed
@emotion/reactand@emotion/styledas they're required for Material-UI styling."id" field required: Each row object must have a unique
idfield. If your data uses a different identifier, map it toidbefore passing to the grid.Editable cells not working: Set
editable: truein your column definitions and handle theonCellEditCommitevent to persist changes.TypeScript errors: If using TypeScript, ensure you're using the correct types from
@mui/x-data-gridfor 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)