DEV Community

Cover image for Simple search form in REACT using hooks 🔎.

Simple search form in REACT using hooks 🔎.

Asim Dahal on September 14, 2019

Searching is one of the most important components of your web application. Let's take an example of an E-commerce platform where there are thousand...
Collapse
 
clarity89 profile image
Alex K. •

Nice tutorial :) One comment - you don't really need to set the filtered results on the state in this case. I'd just filter the people according to the search term during render:

function App() {
  const [searchTerm, setSearchTerm] = React.useState("");
  const handleChange = event => {
    setSearchTerm(event.target.value);
  };

  const results = !searchTerm
    ? people
    : people.filter(person =>
        person.toLowerCase().includes(searchTerm.toLocaleLowerCase())
      );

  return (
    <div className="App">
      <input
        type="text"
        placeholder="Search"
        value={searchTerm}
        onChange={handleChange}
      />
      <ul>
        {results.map(item => (
          <li>{item}</li>
        ))}
      </ul>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Here's a sandbox.

Collapse
 
aa_ziz profile image
Ahmed Aziz •

Thank you, that was really helpful! One quastion: do you know how to make the search accept two seach parameters? like i want to search base on the name and also the address?

This what i tried, and failed :(

function App() {
  const [searchTerm, setSearchTerm] = React.useState("");
  const [searchTerm2, setSearchTerm2] = React.useState("");

  const handleChange = event => {
    setSearchTerm(event.target.value);
  };

  const handleChange2 = event => {
    setSearchTerm2(event.target.value);
  };

  const results = !searchTerm || !searchTerm2
    ? people
    : people.filter(person =>
        person.name.toLowerCase().includes(searchTerm.toLocaleLowerCase())
    ||  person.address.toLowerCase().includes(searchTerm2.toLocaleLowerCase())
      );

  return (
    <div className="App">
      <input
        type="text"
        placeholder="Search name"
        value={searchTerm}
        onChange={handleChange}
      />
      <input
        type="text"
        placeholder="Search address"
        value={searchTerm2}
        onChange={handleChange2}
      />
      <ul>
        {results.map(item => (
          <li>{item}</li>
        ))}
      </ul>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
clarity89 profile image
Alex K. • • Edited

I think it'd be const results = !searchTerm && !searchTerm2 instead of || otherwise the filtering will be applied only of both search terms are present.

Thread Thread
 
aa_ziz profile image
Ahmed Aziz •
  const results =
    searchTerm || searchTerm2
      ? !searchTerm2
        ? people.filter(person =>
            person.name.toLowerCase().includes(searchTerm.toLocaleLowerCase())
          )
        : people.filter(
            person =>
              person.address.toLowerCase() ===
              searchTerm2.toLocaleLowerCase()
          )
      : people;

Enter fullscreen mode Exit fullscreen mode

i came up with this solution and it works now but only if one of the conditions is true. I want to make the method filter the two conditions in the same time. So like i want to know all the people that their name is Alex and lives in New york

Thread Thread
 
clarity89 profile image
Alex K. •

For your specific case you can do like this:

const results = searchTerm && searchTerm2 ?
  people.filter(person =>
    person.name.toLowerCase().includes(searchTerm.toLocaleLowerCase()) &&
    person.address.toLowerCase().includes(searchTerm2.toLocaleLowerCase())
  ) : people

However, note that the filter won't be applied unless both search terms are present.

Thread Thread
 
aa_ziz profile image
Ahmed Aziz •

Yah but that is exactly what i don't want. I want that the user can choose one of the filters or both of them in the sametime

Collapse
 
abdullhrtima profile image
Abdullah Abu Rtima • • Edited

call data from api and filter ....

import React ,{ useState  , useEffect} from 'react';
import axios from 'axios';

export default function Search() {
    const [data ,setData] = useState([]);
    const [filtered ,setFilterd] = useState([]);
    const [result , setResult] = useState("");

    useEffect(()=>{
            const fetchData = async ()=> {
                    try{
                        const res = await axios.get('https://jsonplaceholder.typicode.com/users');
                        setData(res.data);
                        setFilterd(res.data);
                    }catch(err){
                        throw new Error(err);
                    }
                     };
                  fetchData(); 
        },[]);

        useEffect(()=> {
            const results = filtered.filter(res=> res.name.toLowerCase().includes(result)

            ); 
            setData(results)
        } ,[result])
        //console.log(data)

      const onChange =(e)=> {
            setResult(e.target.value);
        }

    return (
        <div>
        <input 
            type="text"
            placeholder="serch here .."
            value={result}
            onChange={onChange}
        />
        {data.map((r,i)=> (   
                <ul key={i}>
                <li>{r.name}</li>
                </ul>)
            )
        }
    </div>
    )  
}

Enter fullscreen mode Exit fullscreen mode
Collapse
 
amitdotcode profile image
amit-dotcode •

codesandbox.io/s/unruffled-bose-tk...

Please Help Me .. See my Code
The problem is when I search in the search field to my note app its work but when I remove search field text my old add data not show only search data show see my code you better understand that what I m trying to say

Collapse
 
moniqueboea profile image
moniqueboea •

Thanks. I tried you exact code and get this warning:

29:6 warning React Hook useEffect has a missing dependency: 'filtered'. Either include it or remove the dependency array react-hooks/exhaustive-deps

Any suggestions?

My search isn't working

Collapse
 
moniqueboea profile image
moniqueboea •

Actually, the search is working. I didn't realize that I had to type lower case. Can that be removed? Most people will start typing names in upper case (at least the first letter).

Collapse
 
rhadimer profile image
Rhadimer Antigua Sánchez •

Excellent!

Collapse
 
riad_bx profile image
Riad •

thanks a lot !! you made my day..

Collapse
 
sapien profile image
Prateek Thapa •

Great.
One nitpick here: Make sure you trim your string for searching. Trim removes all the spaces at the start and end of the string.

people.filter(person => person.toLowerCase().includes(searchTerm.trim()));

Enter fullscreen mode Exit fullscreen mode
Collapse
 
geraldryan profile image
Gerald Ryan •

This is great for simple arrays, but what about arrays of objects and you want the search to be broader in scope. For instance if you want to search a fitness class (which is an object) by name, or by duration, or by intensity or any other property

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀 •

The cover photo looks like the macbook has tin worm 🐛

Collapse
 
asimdahall profile image
Asim Dahal •

🤣🤣 Actually i got the picture from unsplash

Collapse
 
adam_cyclones profile image
Adam Crockett 🌀 •

Okay well whoever took it, they must have been worried about yin worm 😁

Collapse
 
bishwos profile image
Bishwo Shrestha •

Great post

Collapse
 
igorskiy profile image
Ihor Stavratii •

It was realy helpful, thanks!
Maybe somebody know how to implement a feature which would highlight the searched results in the list?

Collapse
 
wanderer3912 profile image
komal3912 •

Such a detailed post! helped a lot to understand hooks. Much appreciated.

Collapse
 
belnako profile image
Belnako •

How do I change the code if I want people to display as a list by default, without typing something in the searchbox?

Collapse
 
moniqueboea profile image
moniqueboea •

Has anyone built a search app that has a form that the user submits and then display the results?

Collapse
 
fatemehqasemkhani profile image
fatemehqasemkhani •

helpful, thanks.

Collapse
 
butonix profile image
Butonix •

Search only starts with a small letter. It doesn't work with the big one

Collapse
 
rockinrone profile image
Ronny Ewanek •

Thanks for this!

Collapse
 
braxhawk profile image
Braxton Hawkins •

Hi, thank you for this post, it was very helpful. I was wondering, is there a way to make the list hidden, and only show when the user is actually searching?

Collapse
 
amitdotcode profile image
amit-dotcode • • Edited

when i try to use this code to filter i m facing this kind of error again and again please help

TypeError: oldData.toLowerCase is not a function

Collapse
 
kareemmarwan profile image
KareemMarwan •

Thx bro

Collapse
 
mariapazmp profile image
Paz Muñoz •

Hi!
What If I have in a separated component the Search Bar from the list of results? I want to know how can I send the results to a parent component :)

Collapse
 
mohammadhani110 profile image
mohammadhani110 •

Love it ! Simple and easy to follow. Thanks alot

Collapse
 
aytaa profile image
Aytaç Ünal •

thanks bro