Search with pagination in Reactjs

In this tutorial, we will see how to create a search with a pagination component in Reactjs.

Search with Pagination in Reactjs

We are going to make use of free pagination API for beer provided by punk API’s.

Using this we will create the search with the pagination in Reactjs.

First, let’s make the raw API call and show the result as it is. By default, the API will return 25 records.

We will make the API call when the component mounts inside the useEffect hook and store the result in the state. After that iterate the result and show it along with the name, tagline, and image.

import { useState, useEffect } from "react";

const API_URL = `https://api.punkapi.com/v2/beers`;

export default function App() {
  const [list, setList] = useState([]);

  const makeApiCall = (url) => {
    fetch(`${url}`)
      .then((resp) => resp.json())
      .then((list) => {
        if (!Array.isArray(list)) {
          setList([]);
        } else {
          setList(list);
        }
      })
      .catch((error) => {
        console.error(error);
      });
  };

  useEffect(() => {
    makeApiCall(API_URL);
  }, []);

  return (
    <div className="App">
      {list.map((e) => (
        <Beer {...e} key={e.name} />
      ))}
    </div>
  );
}

const Beer = ({ name, tagline, image_url }) => {
  return (
    <div>
      <h2>{name}</h2>
      <p>{tagline}</p>
      <img src={image_url} alt={name} width="100px" />
    </div>
  );
};

Now that we are able to fetch the raw data, we will add an input search box above the list and a dropdown to select the pages and navigate through the results.

The search box’s value and pagination’s page will be stored in the different states and these states will be passed as a dependency to the useEffect hook so that whenever any of it changes, a fresh API call is made.

import { useState, useEffect } from "react";

const API_URL = `https://api.punkapi.com/v2/beers`;
const PERPAGE = 25;

export default function App() {
  const [list, setList] = useState([]);
  const [page, setPage] = useState(1);
  const [beerName, setBeerName] = useState("");

  const makeApiCall = (url, page, per_page, beerName) => {
    fetch(
      `${url}?page=${page}&per_page=${per_page}&${
        beerName ? `beer_name=${beerName}` : ""
      }`
    )
      .then((resp) => resp.json())
      .then((list) => {
        if (!Array.isArray(list)) {
          setList([]);
        } else {
          setList(list);
        }
      })
      .catch((error) => {
        console.error(error);
      });
  };

  useEffect(() => {
    makeApiCall(API_URL, page, PERPAGE, beerName);
  }, [page, beerName]);

  return (
    <div className="App">
      <div>
        <label htmlFor="page">Page</label>
        <select
          id="page"
          onChange={(e) => {
            setPage(e.target.value);
          }}
        >
          <option>1</option>
          <option>2</option>
          <option>3</option>
          <option>4</option>
          <option>5</option>
          <option>6</option>
          <option>7</option>
          <option>8</option>
          <option>9</option>
          <option>10</option>
        </select>
        <input
          placeholder="Enter beer name"
          onChange={(e) => setBeerName(e.target.value)}
        />
      </div>
      {list.map((e) => (
        <Beer {...e} key={e.name} />
      ))}
    </div>
  );
}

const Beer = ({ name, tagline, image_url }) => {
  return (
    <div>
      <h2>{name}</h2>
      <p>{tagline}</p>
      <img src={image_url} alt={name} width="100px" />
    </div>
  );
};

Here the PERPAGE is set to a constant value, you can update it to make it dynamic as well.