Greg
Greg

Reputation: 256

React.js: How do you implement search functionality?

I managed to fetch data from API. Now I want to get a specific data from search input without click.I guess I need here filter function. I managed to listen to input from clicking. But how to get data? Any help will be appreciated.
Here is my code


import React, { useState, useEffect } from "react";
import CountryListCard from "./CountryListCard";

import "./CountryList.scss";

export default function CountryList() {
  const [data, setData] = useState([]);
  const [search, setSearch] = useState("");

  const fetchData = () => {
    fetch("https://restcountries.eu/rest/v2/all")
      .then((res) => res.json())
      .then((result) => setData(result))
      .catch((err) => console.log("error"));
  };

  useEffect(() => {
    fetchData();
  }, []);

  function handleChange(e) {
    console.log(e.target.value);
  }
    return (
      <div>
        <input
          className="input"
          type="text"
          placeholder="search country ..."
          value={search}
          onChange={handleChange}
        />
        {data &&
          data.map((country) => (
            <div className="CountryList" key={country.name}>
              <div className="CountryListImg">
                <img src={country.flag} alt="" width="80px" />
              </div>
              <div className="countryName">{country.name}</div>
              <div className="population">{country.population}</div>
              <div className="region">{country.region}</div>
              <div>
                {country.languages.map((language, languageIndex) => (
                  <div key={languageIndex}>{language.name}</div>
                ))}
              </div>
            </div>
          ))}
      </div>
    );
  }




Upvotes: 1

Views: 3143

Answers (3)

Anhdevit
Anhdevit

Reputation: 2104

First, install lodash if you don't have

npm install lodash

And use debounce

// Lodash here <<<<<<<<<<<<<<<<
import { debounce } from 'lodash';

export default function CountryList() {
  const [data, setData] = useState([]);
  const [search, setSearch] = useState("");

  const fetchData = (text) => {
// Fix your API with text search here <<<<<<<<<<<<<<,
    fetch("https://restcountries.eu/rest/v2/all")
      .then((res) => res.json())
      .then((result) => setData(result))
      .catch((err) => console.log("error"));
  };

  useEffect(() => {
    fetchData();
  }, []);

  function handleChange(e) {
    setSearch(e)
    onSearch(e)
    console.log(e.target.value);
  }
  
  const onSearch = debounce((text) => {
      fetchData(text);
  }, 500)

    return (
      <div>
        <input
          className="input"
          type="text"
          placeholder="search country ..."
          value={search}
          onChange={handleChange}
        />
        {data &&
          data.map((country) => (
            <div className="CountryList" key={country.name}>
              <div className="CountryListImg">
                <img src={country.flag} alt="" width="80px" />
              </div>
              <div className="countryName">{country.name}</div>
              <div className="population">{country.population}</div>
              <div className="region">{country.region}</div>
              <div>
                {country.languages.map((language, languageIndex) => (
                  <div key={languageIndex}>{language.name}</div>
                ))}
              </div>
            </div>
          ))}
      </div>
    );
  }

Upvotes: 0

Drew Reese
Drew Reese

Reputation: 202706

You can filter in-line when rendering the data. Remember to do case-insensitive string comparisons

data
  .filter(
    (country) =>
      !search || country.name.toLowerCase().includes(search.toLowerCase())
  )
  .map(country => ...)

If the search is falsey, i.e. "" the filter returns true and country is returned, otherwise the country's name is checked if it includes the search value.

To save the input value

function handleChange(e) {
  const { value } = e.target;
  setSearch(value);
}

Edit react-js-how-do-you-implement-search-functionality

Upvotes: 1

Liu Lei
Liu Lei

Reputation: 1297


useEffect(() => {
  const fetchData = () => {
    fetch("https://restcountries.eu/rest/v2/all")
      .then((res) => res.json())
      .then((result) => setData(result))
      .catch((err) => console.log("error"));
  };
  fetchData();
}, []);

function handleChange(e) {
  setSearch(e.target.value)
}

return (
  <div>
    <input
      className="input"
      type="text"
      placeholder="search country ..."
      value={search}
      onChange={handleChange}
    />
    {data &&
      data.filter(item=> item.name.includes(search)).map((country) => (
        <div className="CountryList" key={country.name}>
          <div className="CountryListImg">
            <img src={country.flag} alt="" width="80px" />
          </div>
          <div className="countryName">{country.name}</div>
          <div className="population">{country.population}</div>
          <div className="region">{country.region}</div>
          <div>
            {country.languages.map((language, languageIndex) => (
              <div key={languageIndex}>{language.name}</div>
            ))}
          </div>
        </div>
      ))}
  </div>
);

Upvotes: 2

Related Questions