Search bars are a great way of helping users find what they need on your website. They are also good for analytics if you keep track of what your visitors are searching for.

You can use React to build a search bar that filters and displays data as the user types. With React hooks and the JavaScript map and filter array methods, the end result is a responsive, functional search box.

The search will take input from a user and trigger the filtering function. You can use a library like Formik to create forms in React, but you can also create a search bar from scratch.

If you don’t have a React project and want to follow along, create one using the create-react-app command.

        npx create-react-app search-bar

In the App.js file, add the form element, including the input tag:

        export default function App() {
   return (
    <div>
        <form>
          <input type="search"/>
        </form>
    </div>
  )
}

You should use the useState React hook and the onChange event to control the input. So, import useState and modify the input to use the state value:

        import { useState } from "React"
export default function App() {
     const [query, setquery] = useState('')
     const handleChange = (e) => {
       setquery(e.target.value)
     }
     return (
      <div>
          <form>
            <input type="search" value={query} onChange={handleChange}/>
          </form>
      </div>
    )
  }

Every time a user types something inside the input element, handleChange updates the state.

Filtering the Data on Input Change

The search bar should trigger a search using the query that the user provides. This means you should filter the data inside the handleChange function. You should also keep track of the filtered data in the state.

First, modify the state to include the data:

        const [state, setstate] = useState({
  query: '',
  list: []
})

Bundling the state values like this, instead of creating one for each value, cuts the number of renders, improving performance.

The data you filter can be anything you want to perform a search on. For example, you can create a list of sample blog posts like this one:

        const posts = [
    {
      url: '',
      tags: ['react', 'blog'],
      title: 'How to create a react search bar',
    },
    {
      url:'',
      tags: ['node','express'],
      title: 'How to mock api data in Node',
    },
    // more data here
  ]

You can also fetch the data using an API from a CDN or a database.

Next, modify the handleChange() function to filter the data whenever the user types inside the input.

        const handleChange = (e) => {
    const results = posts.filter(post => {
        if (e.target.value === "") return posts
        return post.title.toLowerCase().includes(e.target.value.toLowerCase())
    })
    setstate({
        query: e.target.value,
        list: results
    })
}

The function returns the posts without searching through them if the query is empty. If a user has typed a query, it checks whether the post title includes the query text. Converting the post title and the query to lowercase ensures the comparison is case-insensitive.

Once the filter method returns the results, the handleChange function updates the state with the query text and the filtered data.

Displaying the Search Results

Displaying the search results involves looping over the list array using the map method and displaying the data for each item.

        export default function App() {
// state and handleChange() function
   return (
    <div>
        <form>
          <input onChange={handleChange} value={state.query} type="search"/>
        </form>
        <ul>
          {(state.query === '' ? "" : state.list.map(post => {
            return <li key={post.title}>{post.title}</li>
          }))}
        </ul>
    </div>
  )
}

Inside the ul tag, the component checks whether the query is empty. If it is, it displays an empty string because it means the user has not searched for anything. If you want to search through a list of items you are already displaying, remove this check.

If the query is not empty, the map method iterates over the search results and lists the post titles.

You can also add a check that displays a helpful message if the search returns no results.

        <ul>
  {(state.query === '' ? "No posts match the query" : !state.list.length ? "Your query did not return any results" : state.list.map(post => {
    return <li key={post.title}>{post.title}</li>
  }))}
</ul>

Adding this message improves the user experience because the user is not left looking at a blank space.

Handling More Than Once Search Parameter

You can use React state and hooks, together with JavaScript events, to create a custom search element that filters a data array.

The filter function only checks if the query matches one property—title—in the objects inside the array. You can improve the search functionality by using the logical OR operator to match the query to other properties in the object.