Introduction
The Material UI table is one of the most commonly utilized components for building web pages. Surely, if you want to organize and display complex data in the UI efficiently (i.e. reports, scores, comparisons, etc.), then using a table is the right way. Evidently, a well-designed table goes miles long. Indeed, it helps the user improve data readability and clarity of the information presented.
But often, building a table UI from scratch can make a developer break into tears. Hence, this is where user interface libraries like Material UI come to the rescue with their vast ready-to-use component library. So this tutorial will demonstrate how to create a Material UI table in React.js. Starting from the installation and setup, we will dive deeply into popular implementation requirements for Material Table. Additionally, there are plenty of code examples for you to follow. Similarly, using CopyCat saves developers time from writing code from scratch by automatically converting code to production-grade code. Spend time on more interesting and rewarding work: https://copycat.dev/.
At any rate, let’s get started!
Why use Material UI?
Material-UI is one of the top user interface libraries for React.js. Being an open-source project, Material UI features React components that implement Google’s Material Design. Aiming to build a high-quality digital experience, it further helps us create beautiful apps with consistent layouts quickly without compromising performance.
Furthermore, the library provides you with numerous configurable and accessible UI widgets that can be imported and used. The developer no longer needs to write code to create components from scratch, not only is a significant amount of time web development time is saved and can be spent on developing functionalities that matter.
Image: NPM Download Trends
Material UI has key features such as:
- It helps you build light, user-friendly and simple design and layout
- Responsive by default
- Customizable
- Well documented API
- Strong community support
Additionally, check out this insightful article to know more about Material UI features.
Installing Material UI to your React app
Firstly, create a new project using Create React App.
npx create-react-app material-ui-table-demo
Once the project setup is completed, navigate to the project’s root folder.
cd material-ui-table-demo
Finally, add the dependencies to use Material UI in your app.
yarn add @material-ui/core
OR
npm install @material-ui/core
Note: On v5, Material-UI changed its name and is available in NPM under @mui/material.
To know more about the latest release, this article can help you.
Creating a basic table using Material UI
Next, let us learn how to create a basic table UI setup with no frills using Material UI.
Step 1: Create a new file for the Table component inside your project. Here I am naming it BasicTable.js.
Step 2: Import the required material table react.js components here.
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableContainer from "@material-ui/core/TableContainer";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import Paper from "@material-ui/core/Paper";
Step 3: Now, create a function to store our Table row data into an array of objects. I am creating a table to display a shopping bill for this demo.
function createData(number, item, qty, price) {
return { number, item, qty, price };
}
const rows = [
createData(1, "Apple", 5, 3 ),
createData(2, "Orange", 2, 2 ),
createData(3, "Grapes", 3, 1 ),
createData(4, "Tomato", 2, 1.6 ),
createData(5, "Mango", 1.5, 4 )
];
Step 4: Define our table component.
- Within the <TableContainer> wrapper, define the <Table>
- Use <TableHead> and <TableBody> to mark head and body of the table, respectively
- Use <TableRow> to define rows, and <TableCell> defines individual cells within a row.
Our final code looks like this.
import React from "react";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableContainer from "@material-ui/core/TableContainer";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import Paper from "@material-ui/core/Paper";
function createData(number, item, qty, price) {
return { number, item, qty, price };
}
const rows = [
createData(1, "Apple", 5, 3),
createData(2, "Orange", 2, 2),
createData(3, "Grapes", 3, 1),
createData(4, "Tomato", 2, 1.6),
createData(5, "Mango", 1.5, 4)
];
export default function BasicTable() {
return (
<TableContainer component={Paper}>
<Table aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>S.No</TableCell>
<TableCell align="right">Item</TableCell>
<TableCell align="right">Quantity (kg)</TableCell>
<TableCell align="right">Price ($)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow key={row.number}>
<TableCell component="th" scope="row">
{row.number}
</TableCell>
<TableCell align="right">{row.item}</TableCell>
<TableCell align="right">{row.qty}</TableCell>
<TableCell align="right">{row.price}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
Find the final code here.
Finally, here is what the UI looks like with default styling. And guess what? It is responsive!
Implementing Common Features in Material Table
Earlier, we saw how to create a basic table using Material UI. However, the requirement is not often as simple as that. In this session, we learn how to implement a few standard table features using Material UI.
How to show dynamic data in the table column
We often need to populate the table column with dynamic data from an API. This section lets us see how we can achieve this within the Material UI Table using Axios.
Consider we need to display a table containing user details data coming from the mock API https://jsonplaceholder.typicode.com/users. Then the code is as below:
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import Paper from "@material-ui/core/Paper";
import axios from "axios";
function createData(name, username, email, phone, website) {
return { name, username, email, phone, website };
}
const rows = [];
export default function DynamicTable() {
const [data, setData] = useState([]);
useEffect(() => {
axios
.get("https://jsonplaceholder.typicode.com/users")
.then((res) => {
setData(res.data);
console.log("Result:", data);
})
.catch((error) => {
console.log(error);
});
}, []);
return (
<TableContainer component={Paper}>
<Table aria-label="simple table" stickyHeader>
<TableHead>
<TableRow>
<TableCell>Name</TableCell>
<TableCell align="right">Username</TableCell>
<TableCell align="right">Email</TableCell>
<TableCell align="right">Phone</TableCell>
<TableCell align="right">Website</TableCell>
</TableRow>
</TableHead>
<TableBody>
{data.map((row) => (
<TableRow key={row.id}>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell align="right">{row.username}</TableCell>
<TableCell align="right">{row.email}</TableCell>
<TableCell align="right">{row.phone}</TableCell>
<TableCell align="right">{row.website}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
Find the final code here.
How to set the default sorting in Material UI table
Sorting is another common feature we want to implement in our table. In Material UI, we can achieve this using the <TableSortLabel> component. Let us see a code example below.
Suppose we add a sort by ascending or descending functionality to our table’s “Price” column. Then the steps are as follows:
Step 1: Import <TableSortLabel> component.
import TableSortLabel from "@material-ui/core/TableSortLabel";
Step 2: Define 2 constants for storing both the sorted data state and sorting order direction (ASC or DESC) state.
const [rowData, setRowData] = useState(rows);
const [orderDirection, setOrderDirection] = useState("asc");
Step 3: Write functions to handle sorting requests. See below.
const sortArray = (arr, orderBy) => {
switch (orderBy) {
case "asc":
default:
return arr.sort((a, b) =>
a.price > b.price ? 1 : b.price > a.price ? -1 : 0
);
case "desc":
return arr.sort((a, b) =>
a.price < b.price ? 1 : b.price < a.price ? -1 : 0
);
}
};
const handleSortRequest = () => {
setRowData(sortArray(rows, orderDirection));
setOrderDirection(orderDirection === "asc" ? "desc" : "asc");
};
Step 4: Finally, wrap the content of the <TableCell> that needs to be sorted with <TableSortLabel>
<TableCell align="center" onClick={handleSortRequest}>
<TableSortLabel active={true} direction={orderDirection}>
Price ($)
</TableSortLabel>
</TableCell>
Find the final code here.
How to get the total of column records in Material table React.js
Another commonly implemented feature is calculating column values total and displaying them. Let us see an example through code.
Consider we want to find the total price of the items in the bill. Then the code is as below.
import React from "react";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableContainer from "@material-ui/core/TableContainer";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import Paper from "@material-ui/core/Paper";
import { makeStyles } from "@material-ui/core/styles";
const useStyles = makeStyles({
finalRow: {
backgroundColor: "lightblue"
}
});
function createData(number, item, qty, price) {
return { number, item, qty, price };
}
const rows = [
createData(1, "Apple", 5, 3),
createData(2, "Orange", 2, 2),
createData(3, "Grapes", 3, 1),
createData(4, "Tomato", 2, 1.6),
createData(5, "Mango", 1.5, 4)
];
export default function ColumnTotalTable() {
const classes = useStyles();
let totalCost = 0;
// Finding the Total Cost
rows.forEach((row) => (totalCost += row.price));
return (
<TableContainer component={Paper}>
<Table aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>S.No</TableCell>
<TableCell align="right">Item</TableCell>
<TableCell align="right">Quantity (kg)</TableCell>
<TableCell align="right">Price ($)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow key={row.number}>
<TableCell component="th" scope="row">
{row.number}
</TableCell>
<TableCell align="right">{row.item}</TableCell>
<TableCell align="right">{row.qty}</TableCell>
<TableCell align="right">{row.price}</TableCell>
</TableRow>
))}
<TableRow className={classes.finalRow}>
<TableCell align="right" colSpan={4}>
<b>Total Cost:</b> ${totalCost}
</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
);
}
I gave the component a CSS-in-JS styling to differentiate the final row. We can also achieve this by importing the makeStyles hook provided by Material UI.
Check out this article if you’d like to learn more about custom styling.
How to center Material UI table
Following this, we can easily place our Material UI table in the page center through 3 lines of code. For this, I will be making use of CSS-in-JS styling.
Step 1: Define the style for the table with the margin: “auto” using makeStyles hook.
const useStyles = makeStyles({
table: {
width: 400,
margin: "auto"
}
});
Step 2: Within the component, assign constant named classes to useStyles(). This makes it easy to reference.
const classes = useStyles();
Step 3: Finally, map the <Table> component class name to the style we defined in Step 1, accessible as classes.table
<Table aria-label="simple table" className={classes.table}>
That’s it! Our Material UI table is now centered.
You can find the complete code here: https://codesandbox.io/s/gallant-resonance-wgvdd?file=/src/components/CenteredTable.js
How to freeze a column
While scrolling through tables containing many rows and columns, we often want to freeze the column or row to keep them visible. Finally, this section will learn how to achieve this in our material-UI table through quick steps.
Step 1: Define the style to make a column sticky using CSS-in-JS.
const useStyles = makeStyles({
sticky: {
position: "sticky",
left: 0,
background: "white",
boxShadow: "5px 2px 5px grey"
}
});
Step 2: Now, within the component, assign constant named classes to useStyles(). This then makes it easy to reference.
const classes = useStyles();
Step 3: Finally, map the <TableCell> components which we need to freeze with the class name classes.sticky
<TableCell className={classes.sticky}>Name</TableCell>
That’s it! The table column “Name” is now frozen on scrolling. Find the complete code here: https://codesandbox.io/s/gallant-resonance-wgvdd?file=/src/components/FrozenColumnTable.js:1188-1255
Additional Options for Implementing Table using Material UI
Data Grid in Material UI
In addition to the table components, Material UI provides a fast, extendable component called a Data Grid. In fact, using Data Grid, we can display the table data in a grid-like format of rows and columns. Data Grid is also feature-rich, providing implementations for various desirable table features like sorting, filtering pagination, resizing column width, editing row or column, etc.
Do visit the official documentation of Data Grid for more information about editing features like column width and etc.
Material Table for React.js
Alternatively, you can also consider using material-table, a popular library built on top of material-UI that renders React data table components. The library is also highly feature-rich, providing options for searching, sorting, filtering, pagination, and other good things!
Additionally, refer to this video for a detailed tutorial on Material table React.js.
Conclusion
Thus, table UI is a critical component for any data-driven web application. Above all, by using tables, we can powerfully present complex data to users easily to understand. Moreover, this tutorial taught us to implement a basic table in a React app using the popular Material UI library. We learned how to utilize Google’s Material Design features. We also learned to customize our material-UI table by implementing common table features. Here at CopyCat, we make it our mission to convert complex UI designs to developer-friendly code for you to build UI quickly. Check it out here.
We also write more insightful React.js related blogs. Do check them out and let us know what you think. Here are some to start:
- Create Responsive, Component-Based UI Elements Like a Pro with Reactjs Bootstrap
- Create Easy and Smooth React Navigation
- Learn How to Make Drag and Drop with React Draggable
- Everything You Need to Know About React vs React Native
- Complete Guide to Using Material UI Button in React
Once you’ve mastered how to use Material design to make a table, try your hand at making a responsive mui grid or a basic grid. Unlike mui table, the material ui grid responsive layout grid adapts to screen size and orientation. It has an auto layout feature where others will automatically resize if you edit one item around it. The grid system make items always fluid and sized relative to their parent item. Material ui grid can take your data more sophisticated.