FOR DEVELOPERS

How to Create React Search Component Using React Hooks

How to Create React Search Component using React Hooks

A Search Component is a UI element in a software application that allows a user to search for specific information or data. The component typically includes an input field where the user can enter a search query and a button to initiate the search. The search results are displayed to the user in a suitable format, such as a list or table.

The purpose of a Search Component is to provide a simple and efficient way for the user to find the information they are looking for within the application. A well-designed Search Component can significantly improve the user experience and make it easier for users to find what they want.

This article will discuss building a simple React Search Component using some React Hooks like useState and useEffect.

What are React Hooks?

React Hooks are functions in React that allow React developers to add state and side effects to functional components. They were introduced in React 16.8 as an alternative to class components for adding state and logic. React Hooks simplify code and eases the process of building reusable and composable components. This include built-in hooks like useState, useEffect, and useContext, as well as the ability to create custom hooks. You can learn more about it from the React documentation website.

React Hooks are a good choice for creating a search component in React because they allow for reusable, simple, optimized, and easy-to-test components. They simplify the code, make it easier to understand, and only update what has changed for improved performance. These benefits make React Hooks a good choice for building efficient and effective search components in React. We will use the two most common hooks; useState() and useEffect().

Setting up the project

Create a React app called react search component by running the command npx create-react-app react-search-component, then install the axios package by running npm install axios or yarn add axios. After that, open up the app in your preferred code editor, and run the command npm dev or yarn dev to view the app in your browser.

Building the search component

We will build a one-page app that displays facts about different countries. We have created a mock API using the tool mockAPI and populated it with country facts obtained from Fact.net. There will also be a search bar, where one can enter a search query. The country facts that contain the search query will be displayed in real-time when the user enters the search query.

Let us build and style the page. Going into the App.js file, write the following code;

import React from "react";
import "./App.css";

const App = () => { return ( <div className="App"> <header className="header"> <h1 className="page-title">Random Country Facts</h1>

    &lt;div className=&quot;form-input-group&quot;&gt;
      &lt;label className=&quot;search-input-label&quot; htmlFor=&quot;search&quot;&gt;
        &lt;input
          className=&quot;search-input&quot;
          type=&quot;search&quot;
          name=&quot;search&quot;
          id=&quot;search&quot;
          placeholder=&quot;Search...&quot;
          required
        /&gt;
      &lt;/label&gt;
    &lt;/div&gt;
  &lt;/header&gt;

  &lt;main&gt;
    &lt;section className=&quot;cards-wrapper&quot;&gt;
      &lt;article className=&quot;card&quot; key=&quot;index&quot;&gt;
        &lt;h2 className=&quot;short-fact&quot;&gt;Title&lt;/h2&gt;
        &lt;p className=&quot;long-fact&quot;&gt;
          Lorem, ipsum dolor sit amet consectetur adipisicing elit.
        &lt;/p&gt;
        &lt;p className=&quot;country-name&quot;&gt;Country name&lt;/p&gt;
      &lt;/article&gt;
      &lt;article className=&quot;card&quot; key=&quot;index&quot;&gt;
        &lt;h2 className=&quot;short-fact&quot;&gt;Title&lt;/h2&gt;
        &lt;p className=&quot;long-fact&quot;&gt;
          Lorem, ipsum dolor sit amet consectetur adipisicing elit.
        &lt;/p&gt;
        &lt;p className=&quot;country-name&quot;&gt;Country name&lt;/p&gt;
      &lt;/article&gt;
    &lt;/section&gt;
  &lt;/main&gt;
&lt;/div&gt;

); };

export default App;

From the code above, we have a header element containing our project's title and search input. We also have a main element containing an article element card that contains the dummy text, which will display the facts fetched later. Let us style them by adding the following code to our App.css file.

* {
box-sizing: border-box;
}
html,
body {
overflow-x: hidden;
}
body {
padding: 0 30px;
color: #434341;
max-width: 1400px;
margin: auto;
}

/* header */ .header { padding: 20px 0; text-align: center; } .page-title { margin: 0 0 20px; } .form-input-group { display: flex; width: 100%; max-width: 400px; margin: auto; } .search-input-label { border-radius: 5px; flex-grow: 1; } .search-input { width: 100%; border: 1px solid #ddd; padding: 5px 10px; border-radius: 5px; } .search-input:focus { outline: #434341; } .search-button { padding: 5px 10px; border-radius: 0 5px 5px 0; border: 1px solid #ddd; background-color: #eee; }

/* cards */ .cards-wrapper { display: grid; gap: 20px; grid-template-columns: repeat(3, 1fr); margin: 40px 0 80px; } @media screen and (max-width: 960px) { .cards-wrapper { grid-template-columns: repeat(2, 1fr); } } @media screen and (max-width: 786px) { .cards-wrapper { grid-template-columns: repeat(1, 1fr); } } .card { border: 1px solid #ddd; border-radius: 5px; padding: 5px 20px; box-shadow: 4px 4px 4px 0px #eee; } .country-name { border: 2px solid #eee; border-radius: 5px; width: max-content; padding: 5px; }

Let us view the changes in the browser.

Building search components in React.js.webp

This looks great. Now let us fetch our data and display it on the page. Returning to our App.js, we import axios from the axios package we installed earlier to fetch our data. We also import the React hooks from React, useEffect, and UseState.

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

The useState hook allows components to have state variables, which can change over time and trigger re-renders without using class components, while the useEffect hook allows components to perform side effects, such as updating the component's state or interacting with APIs, in response to changes in component's props or state.

We create two states called isLoading and FactsFata using the useState hook. The isLoading variable is a boolean we use to condition what we render on the screen. The factsData is an empty array that will hold the data we fetch. And while we fetch our data, a loading message will be displayed to the user until our data has been fetched and is ready to be displayed.

const App = () => {
const [isloading, setIsloading] = useState(true);
const [FactsData, setFactsData] = useState([]);
…
export default App;

Next, we write the function to fetch and store our data.

useEffect(() => {
axios
.get(https://63db4515b8e69785e47e7435.mockAPI.io/country)
.then((response) => {
setFactsData(response.data);
setIsloading(false);
})
.catch((err) => {
console.log(err);
});
}, []);

Below our states, we have written our function within a useEffect hook. This function fetches data from the mock API created and stores it in the fetchData state. After that, it sets the IsLoading state from true to false. Now, let us output the data to the user. Replace the current code within the main element with the following;

 <main>
{isloading ? (
<p className="message">loading...</p>
) : (
<section className="cards-wrapper">
{factsData.map((data) => (
<article className="card" key="index">
<h2 className="short-fact">{data.shortFact}</h2>
<p className="long-fact">{data.longFact}</p>
<p className="country-name">{data.country}</p>
</article>
))}
</section>
)}
</main>

We created a ternary operator to conditionally render different UI elements depending on the value of the isloading variable. If isloading is true, it displays a p element with the text "loading...". If isloading is false, it maps over the factsData array and creates a card for each item, displaying a short fact, a long fact, and a country name. Let us view it in our browser.

Displaying data using isLoading..webp

Next, let us get the search query from the search bar and store it in a state.

const [searchInput, setSearchInput] = useState("");
…

<input className="search-input" type="search" name="search" id="search" placeholder="Search..." value={searchInput} onChange={(e) => { setSearchInput(e.target.value); }} required />

From the code above, we created a state called searchInput, initially set to an empty string, and then the value of our input element was set to the searchInput state variable. We also added an onChange attribute to the input element, which sets the searchInput state variable to the query the user enters. If you log the searchInput state variable to the console and enter a search query, you will see the value output as you type in the query.

Let us now show specific results based on the user’s search query.

We create a state called filteredResults to store our filtered result with an empty array as its initial value.

const [filteredResults, setFilteredResults] = useState([]);

We also create a react search bar function within another useEffect hook for our search bar component.

useEffect(() => {
const filteredData = factsData.filter((fact) => {
return Object.values(fact)
.join("")
.toLowerCase()
.includes(searchInput.toLowerCase());
});
setFilteredResults(filteredData);
}, [factsData, searchInput]);

This React search function updates the state of filteredResults based on the changes in the variables factsData and searchInput, which we passed in as a second argument to the useEffect hook telling React to run this effect only when either of these values changes.

It filters the factsData array based on whether the string representation of the fact object's values contains the lowercase value of searchInput. The filtered data is then stored in filteredData and set as the value of filteredResults using setFilteredResults.

Next we go back into our main element and include another ternary operator within the section element to render either the fetched data or filtered result.

<main>
{isloading ? (
<p className="message">loading...</p>
) : (
<section className="cards-wrapper">
{filteredResults.length === 0
? factsData.map((data) => (
<article className="card" key="index">
<h2 className="short-fact">{data.shortFact}</h2>
<p className="long-fact">{data.longFact}</p>
<p className="country-name">{data.country}</p>
</article>
))
: filteredResults.map((data) => (
<article className="card" key="index">
<h2 className="short-fact">{data.shortFact}</h2>
<p className="long-fact">{data.longFact}</p>
<p className="country-name">{data.country}</p>
</article>
))}
</section>
)}
</main>

This second ternary operator checks the length of the filteredResults array. If it is equal to 0, it maps over the factsData array, and for each item in the array, it creates a card for each fact.

If the length of the filteredResults array is not equal to 0, then it maps over the filteredResults array and creates a card for each item in the same way described above.

filteredResult array using React.JS.webp

Our final code should look like this.

import React, { useEffect, useState } from "react";
import "./App.css";
import axios from "axios";

const App = () => { const [isloading, setIsloading] = useState(true); const [factsData, setFactsData] = useState([]); const [searchInput, setSearchInput] = useState(""); const [filteredResults, setFilteredResults] = useState([]);

useEffect(() => { axios .get(https://63db4515b8e69785e47e7435.mockAPI.io/country) .then((response) => { setFactsData(response.data); setIsloading(false); }) .catch((err) => { console.log(err); }); }, []);

useEffect(() => { const filteredData = factsData.filter((fact) => { return Object.values(fact) .join("") .toLowerCase() .includes(searchInput.toLowerCase()); }); setFilteredResults(filteredData); }, [factsData, searchInput]);

return ( <div className="App"> <header className="header"> <h1 className="page-title">Random Country Facts</h1>

    &lt;form className=&quot;form-input-group&quot;&gt;
      &lt;label className=&quot;search-input-label&quot; htmlFor=&quot;search&quot;&gt;
        &lt;input
          className=&quot;search-input&quot;
          type=&quot;search&quot;
          name=&quot;search&quot;
          id=&quot;search&quot;
          placeholder=&quot;Search...&quot;
          value={searchInput}
          onChange={(e) =&gt; {
            setSearchInput(e.target.value);
          }}
          required
        /&gt;
      &lt;/label&gt;
    &lt;/form&gt;
  &lt;/header&gt;

  &lt;main&gt;
    {isloading ? (
      &lt;p className=&quot;message&quot;&gt;loading...&lt;/p&gt;
    ) : (
      &lt;section className=&quot;cards-wrapper&quot;&gt;
        {filteredResults.length === 0
          ? factsData.map((data) =&gt; (
              &lt;article className=&quot;card&quot; key=&quot;index&quot;&gt;
                &lt;h2 className=&quot;short-fact&quot;&gt;{data.shortFact}&lt;/h2&gt;
                &lt;p className=&quot;long-fact&quot;&gt;{data.longFact}&lt;/p&gt;
                &lt;p className=&quot;country-name&quot;&gt;{data.country}&lt;/p&gt;
              &lt;/article&gt;
            ))
          : filteredResults.map((data) =&gt; (
              &lt;article className=&quot;card&quot; key=&quot;index&quot;&gt;
                &lt;h2 className=&quot;short-fact&quot;&gt;{data.shortFact}&lt;/h2&gt;
                &lt;p className=&quot;long-fact&quot;&gt;{data.longFact}&lt;/p&gt;
                &lt;p className=&quot;country-name&quot;&gt;{data.country}&lt;/p&gt;
              &lt;/article&gt;
            ))}
      &lt;/section&gt;
    )}
  &lt;/main&gt;
&lt;/div&gt;

); };

export default App;

Conclusion

That's it on building a Search Component in React using some React Hooks. This can be further customized by adding a button to the react search bar component and displaying the result only when the button is clicked.

You can find the source code on GitHub and interact with the app.

Author

  • How to Create React Search Component Using React Hooks

    Timonwa Akintokun

    Timonwa is a front-end engineer and technical writer who excels at both development and communication. She has a love for learning and sharing knowledge, and is always seeking out new opportunities to grow and share her expertise.

Frequently Asked Questions

You can create a search component in Reactjs by using a text input field and a button to trigger the search functionality. The text input field can capture the user's search query, and the button can be clicked to initiate the search.

You can get the search input value in React by using the "onChange" event listener on the text input field. This will allow you to capture the user's input as they type, and update the search query accordingly.

You can create a dynamic search box in Reactjs by using the "useState" hook to manage the state of the search query. You can then pass the search query as a prop to your search component, and use it to filter your search results dynamically as the user types.

View more FAQs
Press

Press

What’s up with Turing? Get the latest news about us here.
Blog

Blog

Know more about remote work. Checkout our blog here.
Contact

Contact

Have any questions? We’d love to hear from you.

Hire remote developers

Tell us the skills you need and we'll find the best developer for you in days, not weeks.