Given a list of users, build a user data table that displays users in a paginated format.
1import { useState } from 'react';2import users from './data/users';34type User = (typeof users)[number];56const columns = [7 { label: 'ID', key: 'id' },8 { label: 'Name', key: 'name' },9 { label: 'Age', key: 'age' },10 { label: 'Occupation', key: 'occupation' },11] as const;1213function paginateUsers(usersList: Array<User>, page: number, pageSize: number) {14 const start = (page - 1) * pageSize;15 const end = start + pageSize;1617 const pageUsers = usersList.slice(start, end);18 const totalPages = Math.ceil(usersList.length / pageSize);19 return { pageUsers, totalPages };20}2122export default function DataTable() {23 const [page, setPage] = useState(1);24 const [pageSize, setPageSize] = useState(5);2526 const { totalPages, pageUsers } = paginateUsers(users, page, pageSize);2728 return (29 <div>30 <table>31 <thead>32 <tr>33 {columns.map(({ label, key }) => (34 <th key={key}>{label}</th>35 ))}36 </tr>37 </thead>38 <tbody>39 {pageUsers.map(({ id, name, age, occupation }) => (40 <tr key={id}>41 <td>{id}</td>42 <td>{name}</td>43 <td>{age}</td>44 <td>{occupation}</td>45 </tr>46 ))}47 </tbody>48 </table>49 <hr />50 <div className="pagination">51 <select52 aria-label="Page size"53 onChange={(event) => {54 setPageSize(Number(event.target.value));55 setPage(1);56 }}>57 {[5, 10, 20].map((size) => (58 <option key={size} value={size}>59 Show {size}60 </option>61 ))}62 </select>63 <div className="pages">64 <button65 disabled={page === 1}66 onClick={() => {67 setPage(page - 1);68 }}>69 Prev70 </button>71 <span aria-label="Page number">72 Page {page} of {totalPages}73 </span>74 <button75 disabled={page === totalPages}76 onClick={() => {77 setPage(page + 1);78 }}>79 Next80 </button>81 </div>82 </div>83 </div>84 );85}
Data tables are frequently asked about during front-end interviews, as displaying paginated data with filtering functionality is a UI pattern built at almost every company.
Since the table skeleton has been provided, we can focus on the state and data manipulation aspects of the data table.
State is straightforward. Only two state values are needed: the current page and the page size. Since the data does not change in this case, there's no need for the user data to be part of state.
These state values are manipulated by the page size <select> and prev/next buttons.
The maximum number of pages can be derived from the number of users divided by the page size, so it does not need to be part of state.
We implement a function paginateUsers that takes in the list of users, the page number, and the page size. It will return the list of users for the current page and the total number of pages.
To determine the list of users for the current page, we can determine the start and end indices, then use Array.prototype.slice() to extract the appropriate slice from the users list:
Array.prototype.slice(), it doesn't matter if the end index exceeds the size of the list.paginateUsers() will be called in the render path, and the returned pageUsers array contains the current page of users to be rendered. The rendering code doesn't need to be changed much.
Some other user experience improvements we can make:
console.log() statements will appear here.