ReactHustle

How to Create A React Searchable Table with MUI

Jasser Mark Arioste

Jasser Mark Arioste

How to Create A React Searchable Table with MUI

Hello! In this tutorial, you'll learn how to create a searchable table in React using MUI components and implementing a custom backend search logic.

Introduction #

A search feature is always a useful feature in many applications. It allows the user to save time by immediately finding the data they want. Sometimes, we'll be tasked with implementing a search feature for a list, table, or page.

We're going to use NextJS as our react framework so that we can easily create the backend logic to display the data. For tutorial purposes, we're also going to use https://dummyjson.com/ for fetching our data.

For the front-end, since MUI has awesome built-in components such as TextField and Table, you'll be able to implement this feature fairly quickly.

Step 1: Project Setup #

First, let's create a new NextJS project by invoking the following command:

npx create-next-app@latest --ts --app react-search-table-tutorial

This will create a new NextJS app with typescript using the new /app directory. After that's done, you can start the local development server by running the command:

cd react-search-table-tutorial
yarn dev
# or
npm run dev

Step 2: Creating the Custom Backend Logic #

Next, let's first create the custom backend logic. Let's assume that you are going to implement a table for users. Create the file /app/users/route.ts and copy the following code:

// app/users.route.ts
import { NextResponse } from "next/server";

export type User = {
  id: number;
  firstName: string;
  lastName: string;
  maidenName: string;
  age: number;
  gender: string;
  email: string;
  phone: string;
  username: string;
  password: string;
  birthDate: string;
};

type DummyJSONResponse = {
  users: User[];
};

/**
 * A proxy for https://dummyjson.com to simulate calls to database
 * @param request
 * @returns
 */
export async function GET(request: Request) {
  const url = new URL(request.url);
  const params = url.searchParams;

  // select the properties that we need
  params.append(
    "select",
    "id,firstName,lastName,maidenName,age,gender,email,phone,username,password,birthDate"
  );

  // use different a base url if there's a search query
  const hasSearch = params.has("search");
  let baseUrl = `https://dummyjson.com/users`;
  if (hasSearch) {
    params.append("q", params.get("search")!);
    params.delete("search");
    baseUrl = `https://dummyjson.com/users/search`;
  }

  const dummyUrl = new URL(baseUrl);

  //copy all the search params to dummyURL
  params.forEach((val, key) => {
    dummyUrl.searchParams.append(key, val);
  });

  const response = await fetch(dummyUrl);

  //return the response
  const data = (await response.json()) as DummyJSONResponse;
  return NextResponse.json(data.users);
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758

Explanation:

This fetches data from dummyjson.com REST API. First, we parse the query and reconstruct it before calling dummyjson.com's REST API. To test this, you can go to the route http://localhost:3000/users and it will give you a similar result below.

Users API without Search

Now if you add a query parameter, for example http://localhost:3000/users?search=terry, It should give you filtered results like so:

Users API with Search

Now that we have the search logic working in the backend, all that's left is to display the data in the front end and create a search input component!

Step 3: Installing MUI #

To Implement components quickly, we're going to use MUI. MUI is one of the most popular react libraries and it provides react components that are easy to use and well-documented.

Let's install MUI in our NextJS project by running the command:

yarn add @mui/material @emotion/react @emotion/styled

Optionally, you can also install MUI icons:

yarn add @mui/icons-material

For a more in-depth explanation of the installation, you can go to the MUI installation docs.

Step 4: Installing additional Useful Libraries #

In this tutorial, we're not going to use Next 13's SSR feature. Instead, we're going to do it the old-fashioned way by fetching data from the client. When fetching data from the client I'd like to use the useFetch hook from usehooks-ts library so let's install that.

yarn add usehooks-ts

Step 5: Creating The UsersTable Component #

Next is to create the component, first let's create the file components/UsersTable.tsx.

// components/UsersTable.tsx
"use client";
const UsersTable = () => {
  return <div>UsersTable</div>;
};
export default UsersTable;
123456

Now, let's modify the file 'app/page.tsx' to use the <UsersTable/> component:

// app/page.tsx
import UsersTable from "@/components/UsersTable";

export default function Home() {
  return (
    <main>
      <UsersTable />
    </main>
  );
}
12345678910

Now, when you go to localhost:3000, you should see the following output:

Users Table Creation

Step 6: Fetching and Displaying Data #

Next, you're going to fetch and display data from the backend. Modify your UsersTable.tsx file to the following code:

"use client";

import { User } from "@/app/users/route";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableRow,
} from "@mui/material";
import { useFetch } from "usehooks-ts";

const UsersTable = () => {
  const { data } = useFetch<User[]>("/users");
  return (
    <div>
      <Table>
        <TableHead>
          <TableCell>ID</TableCell>
          <TableCell>Email</TableCell>
          <TableCell>Username</TableCell>
          <TableCell>First name</TableCell>
          <TableCell>Last name</TableCell>
          <TableCell>Gender</TableCell>
          <TableCell>Phone</TableCell>
        </TableHead>
        <TableBody>
          {data?.map((user) => {
            return (
              <TableRow key={user.id}>
                <TableCell>{user.id}</TableCell>
                <TableCell>{user.email}</TableCell>
                <TableCell>{user.username}</TableCell>
                <TableCell>{user.firstName}</TableCell>
                <TableCell>{user.lastName}</TableCell>
                <TableCell>{user.gender}</TableCell>
                <TableCell>{user.phone}</TableCell>
              </TableRow>
            );
          })}
        </TableBody>
      </Table>
    </div>
  );
};
export default UsersTable;
12345678910111213141516171819202122232425262728293031323334353637383940414243444546

Explanation: 

First, we use the useFetch() hook to fetch data from our previously created route /users. Next, we use MUI Table components to display the data.

After this step, you should get the following result:

React Searchable Table with Data

Step 7: Adding Search Functionality #

In this step, we're going to implement the search functionality.

First, add a state to hold the search input using the useState hook and modify the URL to include the search parameter if there's a value. To prevent multiple calls to the /users route, let's add a denounced state using the useDebounce hook.

// components/UsersTable.tsx
const UsersTable = () => {
  const [search, setSearch] = useState("")
  const debouncedValue = useDebounce(search, 600);
  const url = debouncedValue ? "/users?search=" + debouncedValue : "/users";
  
  const { data } = useFetch<User[]>(url);
 //...
}
123456789

Next, add a <TextField/> component to modify the search state. 

// components/UsersTable.tsx
const UsersTable = ()=> {
  //...
   return (
    <div>
      <TextField value={search} onChange={(e) => setSearch(e.target.value)} />
      // ...
    </div>
  )
}
12345678910

That's basically it! You've implemented a table with search functionality with MUI components. Below is the output:

React searchable table with Search filter

Full Code and Demo #

The full code can be accessed on Github: jmarioste/react-search-table-tutorial. The demo can be accessed at Stackblitz: React Search Table Tutorial

Conclusion #

You learned how to implement a basic react table with search functionality with ease. First, we created a backend API that allows us to search the data. Next, we implemented the frontend to display and interact with the data.

If you like this tutorial, please leave a like or share this article. For future tutorials like this, please subscribe to our newsletter or follow me on GitHub.

Resources #

If you need more information about the framework, and libraries used in this tutorial, please refer to their respective documentation.

Credits: Image by wal_172619 from Pixabay

Share this post!

Related Posts