React provides the flexibility to create dynamic and responsive tables, allowing developers to display, style and interact with data easily.
Understanding Tables in React
A table in HTML consists of rows and columns, where each row is represented by a <tr> element, each cell by a <td> element, and the header cells by <th>. In React, these elements are used within components to create dynamic tables.
React allows developers to render tables based on arrays or objects, making it possible to generate rows and columns dynamically with minimal code.
Basic Table Structure in React
A simple static table in React can be created using JSX as follows:
import React from 'react';
function SimpleTable() {
return (
<table>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>City</th>
</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>25</td>
<td>New York</td>
</tr>
<tr>
<td>Jane</td>
<td>30</td>
<td>Chicago</td>
</tr>
</tbody>
</table>
);
}
export default SimpleTable;
In this example:
- <table> represents the table structure.
- <thead> contains <tr> and <th> elements, representing the header row.
- <tbody> holds rows (<tr>) and cells (<td>) for each data entry.
This example shows a static table, but in most cases, data is dynamic and stored in arrays or objects.
Creating Dynamic Tables in React with map( )
When data comes from an array, we can use the map( ) function to create rows dynamically. Let’s say we have an array of objects representing people’s information:
import React from 'react';
const people = [
{ id: 1, name: 'Alice', age: 24, city: 'San Francisco' },
{ id: 2, name: 'Bob', age: 28, city: 'Los Angeles' },
{ id: 3, name: 'Charlie', age: 32, city: 'New York' }
];
function DynamicTable() {
return (
<table>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>City</th>
</tr>
</thead>
<tbody>
{people.map(person => (
<tr key={person.id}>
<td>{person.name}</td>
<td>{person.age}</td>
<td>{person.city}</td>
</tr>
))}
</tbody>
</table>
);
}
export default DynamicTable;
In this example:
- people.map( ) iterates over each person in the people array.
- Each person object generates a <tr> element with data in <td> cells.
- A key attribute (using person.id) ensures React efficiently tracks each row.
Adding Styling to React Tables
Tables in React can be styled using CSS or inline styles. Here’s an example of a table with basic CSS styling:
/* In a CSS file */
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 8px;
text-align: left;
border: 1px solid #ddd;
}
th {
background-color: #f2f2f2;
}
Apply this styling by importing the CSS file into the component:
import React from 'react';
import './TableStyles.css'; // Assuming the CSS file is named TableStyles.css
const people = [
{ id: 1, name: 'Alice', age: 24, city: 'San Francisco' },
{ id: 2, name: 'Bob', age: 28, city: 'Los Angeles' },
{ id: 3, name: 'Charlie', age: 32, city: 'New York' }
];
function StyledTable() {
return (
<table>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>City</th>
</tr>
</thead>
<tbody>
{people.map(person => (
<tr key={person.id}>
<td>{person.name}</td>
<td>{person.age}</td>
<td>{person.city}</td>
</tr>
))}
</tbody>
</table>
);
}
export default StyledTable;
This CSS styling gives the table a structured look, making it visually appealing and easier to read.
Handling Large Datasets with Pagination
For large datasets, pagination is essential to improve usability. In React, this can be achieved by slicing the data array based on the current page number. Here’s a basic example of paginated tables:
import React, { useState } from 'react';
const people = [
{ id: 1, name: 'Alice', age: 24, city: 'San Francisco' },
// Assume this array contains many more entries
];
function PaginatedTable() {
const [currentPage, setCurrentPage] = useState(1);
const rowsPerPage = 10;
const indexOfLastRow = currentPage * rowsPerPage;
const indexOfFirstRow = indexOfLastRow - rowsPerPage;
const currentRows = people.slice(indexOfFirstRow, indexOfLastRow);
const handleNext = () => setCurrentPage(prevPage => prevPage + 1);
const handlePrevious = () => setCurrentPage(prevPage => Math.max(prevPage - 1, 1));
return (
<div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>City</th>
</tr>
</thead>
<tbody>
{currentRows.map(person => (
<tr key={person.id}>
<td>{person.name}</td>
<td>{person.age}</td>
<td>{person.city}</td>
</tr>
))}
</tbody>
</table>
<button onClick={handlePrevious} disabled={currentPage === 1}>Previous</button>
<button onClick={handleNext}>Next</button>
</div>
);
}
export default PaginatedTable;
In this example:
- slice() is used to display a subset of people based on the current page.
- handleNext and handlePrevious update currentPage to navigate between pages.
- The table dynamically updates based on currentPage.
Sorting and Filtering Data in React Tables
Sorting and filtering data are common requirements for dynamic tables. Here’s a basic example of sorting data by clicking on table headers:
import React, { useState } from 'react';
const initialData = [
{ id: 1, name: 'Alice', age: 24, city: 'San Francisco' },
{ id: 2, name: 'Bob', age: 28, city: 'Los Angeles' },
{ id: 3, name: 'Charlie', age: 32, city: 'New York' }
];
function SortableTable() {
const [data, setData] = useState(initialData);
const [sortOrder, setSortOrder] = useState(true); // true for ascending
const sortByName = () => {
const sortedData = [...data].sort((a, b) => {
if (a.name < b.name) return sortOrder ? -1 : 1;
if (a.name > b.name) return sortOrder ? 1 : -1;
return 0;
});
setData(sortedData);
setSortOrder(!sortOrder);
};
return (
<table>
<thead>
<tr>
<th onClick={sortByName} style={{ cursor: 'pointer' }}>Name</th>
<th>Age</th>
<th>City</th>
</tr>
</thead>
<tbody>
{data.map(person => (
<tr key={person.id}>
<td>{person.name}</td>
<td>{person.age}</td>
<td>{person.city}</td>
</tr>
))}
</tbody>
</table>
);
}
export default SortableTable;
In this example:
- sortByName sorts data by name in ascending or descending order based on sortOrder.
- sortOrder is toggled with each click to change the sorting direction.