Skip to content

Instantly share code, notes, and snippets.

@Neeraj1005
Last active August 30, 2022 14:06
Show Gist options
  • Save Neeraj1005/11932c9a1786318325f17a4ab506993c to your computer and use it in GitHub Desktop.
Save Neeraj1005/11932c9a1786318325f17a4ab506993c to your computer and use it in GitHub Desktop.
Using useEffect create search filter in NextJs

Add Search filter in NextJs using useState and useEffect

index.js

import Layout from "../../components/Layout";
import { NextSeo } from "next-seo";
import { useState, useEffect } from "react";
import CitiesComponent from "../../components/CitiesComponent";

const topCity = () => {
  /**
   * get all cities array
   */
  const [cities, setCities] = useState([]);
  /**
   * loding indicator
   */
  const [loading, setLoading] = useState(false);
  /**
   * input field keyword onchage
   */
  const [search, setSearch] = useState("");
  /**
   * loop over the cities
   */
  const [filteredCities, setFilteredCities] = useState([]);

  /**
   * Fetch api
   */
  useEffect(() => {
    setLoading(true);
    fetch(`https://restcountries.eu/rest/v2/all`)
      .then((res) => res.json())
      .then((data) => {
        setCities(data);
        setLoading(false);
      })
      .catch((err) => {
        console.log(err);
      });
  }, []);

  /**
   * fetch this effect while entering the keywords
   */
  useEffect(() => {
    setFilteredCities(
      cities.filter((city) =>
        city.name.toLowerCase().includes(search.toLowerCase())
      )
    );
  }, [search, cities]);

  if (loading) {
    return <div>Loading...</div>;
  }

  return (
    <Layout>
      <NextSeo
        title={`Top cities`}
        description={`Top cities `}
        openGraph={{
          title: `Top cities`,
          description: `Top cities `,
        }}
      />
      <input
        type="text"
        placeholder="Search Cities"
        onChange={(e) => setSearch(e.target.value)}
      />
      <div className="flex">
        <div className="w-screen mb-5 px-4 md:px-5">
          <div className="flex flex-wrap -mx-1 lg:-mx-4">
            {filteredCities.map((city, ids) => (
              <CitiesComponent key={ids} {...city} />
            ))}
          </div>
        </div>
      </div>
    </Layout>
  );
};
export default topCity;

component CitiesComponent.js

import Link from 'next/link';
const CitiesComponent = ( props ) => {
    const {name, flag} = props;
    return (
        <div
        key={name}
        className="px-1 w-full md:w-1/2 lg:my-2 lg:px-4 lg:w-1/6"
      >
        <Link href={`/countries/${name}`}>
          <a
            className="shover:underline hover:text-blue-500"
            target="_blank"
            rel="noopener noreferrer"
          >
            {name}
          </a>
        </Link>
      </div>
    )
}

export default CitiesComponent
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment