React Navbar with Search Bar from Scratch

The search bar is one of the most important parts of the navigation menu. Search option in any web app provides a better user experience. Whether it is a simple blog or a big e-commerce, users always want to search for something on the website.

So it’s very important to have search functionality in your application. Before we dive in, please read this blog post till the end. I will explain all the code as simple as possible.

What You Are Going to Learn in This Blog Post

React navbar with search bar demo.

You will find in this blog post:

  • Placement of search box component in the navigation menu.
  • Learning about React router. That means, when the user clicks on the search box, It will redirect to the search page using React Router’s useNavigate hook.
  • You will learn about transferring variable data between components.
  • Finally, you can able to create search functionality with the help of maps and filters.
  • At the end of this tutorial, you will get the full source code of this demo on GitHub.

So read this blog post carefully. And be able to add a search option to the navbar in your React web application.

Project Structure

In this case, I’m using Vite. If you use the Create React App (CRA) it will also work fine. But I prefer Vite over CRA. Here’s an in-depth blog post on why I choose Vite over CRA.

In the above image, you can see that some JSON data is kept in the assets folder. The component folder contains the navigation component and page components.

React Navbar with Search Bar: Step-by-Step Tutorial

So without further ado let’s get down to business. First, create a React project. You can start a React app project with CRA, Vite, or Next.js. Or you can also work on your existing project. Whatever you feel comfortable with.

Step 1: Add Search Bar into the React Navbar

First, create a React Navbar component with a search input box.

import { NavLink } from "react-router-dom";
import { useState, useEffect } from "react";

//Create Navbar component
function Navbar({ queryData, searchBox }) {
  const [query, setQuery] = useState("");

  const onChangeFunction = (e) => setQuery(e.target.value);

  useEffect(() => {
    queryData(query);
  }, [query]);

  return (
    <div>
      <nav className="nav">
        <ul>
          <li>
            <NavLink to="/">Home</NavLink>
          </li>
          <li>
            <NavLink to="/blog">Blog</NavLink>
          </li>
          <li>
            {/* Add a search box to the Navbar */}
            <input
              type="text"
              placeholder="Search a name..."
              value={query}
              onChange={onChangeFunction}
              onClick={searchBox}
            ></input>
          </li>
        </ul>
      </nav>
    </div>
  );
}

export default Navbar;

This is the Navbar.jsx file in the project’s component folder.

Code Explanation:

Here a navigation menu is created using the <nav> tag. And Three options are given in the menu. The options are respectively: Home, Blog, and Search Box.

Instead of React Router’s traditional <Link> tag, I used <NavLink> in the home and blog options. Why I’m using this? Read: React Navbar Highlight Current Page with NavLink to learn more about this topic.

But since this tutorial is about the search box, I won’t discuss the home and blog options in this post.

So, in the third option of the navigation bar, I have created a search input box through the <input> tag.

Now notice that several attributes are given in the input tag. Not much to say about the traditional type and placeholder attributes. Just basic HTML.

The onChange attribute within the input tag is very important. This is when the user types something in the search input box this onChange event will be called.

Here onChange={onChangeFunction} means the onChange event handler will execute the onChangeFunction function when the user types something in the input box.

Now let’s look at the onChangeFunction function. It is simply a function that stores the input box data in the query state variable.

Now look at the onClick event handler for the <input> tag. That is, when the user taps or clicks on the search box, the searchBox method will be called.

Here searchBox is a callback prop of the Navbar component. That is, any function of the parent component can be called through it. You will get more details on this later.

Now let’s talk about the state variable I mean hook. Why do I use useState and useEffect in the Navbar component? To know this, it is important to understand the workflow of the search box in this project.

In the above image, you will get a clear idea about the workflow of the search box. We need to send the data that the user types in the search box to the parent App component. For this reason, we have used the useState hook so that whenever the user types something new we can capture that value in the query variable.

After that, whenever the value of the query variable changes, the useEffect hook will execute the queryData callback method. queryData is a callback method of the parent App component. It sends the updated value of the query state variable to the App component.

Step 2: Adding Some Styles

body {
  margin: 0;
  padding: 0;
}

.nav {
  background-color: black;
  display: flex;
  justify-content: center;
  align-items: center;
  padding-top: 20px;
  padding-bottom: 20px;
}

.nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: 30px;
}

.nav a {
  text-decoration: none;
  font-size: 30px;
}

.nav a:not(.active) {
  color: red;
}

.active {
  font-weight: bold;
  color: white;
}

.nav input {
  border: none;
  padding-left: 10px;
  height: 30px;
}

This is the App.css file. Here is a simple Navbar design in CSS. You can design it any way you like.

Step 3: Create the App Component

import "./App.css";
import Navbar from "./component/Navbar";
import Blog from "./component/pages/Blog";
import Home from "./component/pages/Home";
import Search from "./component/pages/Search";
import { Route, Routes, useNavigate } from "react-router-dom";
import { useState } from "react";

function App() {
  const [searchQuery, setSearchQuery] = useState("");
  const callFromNavbar = (value) => {
    setSearchQuery(value);
  };

  const navigate = useNavigate();
  const searchPage = () => {
    navigate(`/search`);
  };

  return (
    <div>
      <Navbar queryData={callFromNavbar} searchBox={searchPage} />
      <div>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/blog" element={<Blog />} />
          <Route path="/search" element={<Search search={searchQuery} />} />
        </Routes>
      </div>
    </div>
  );
}

export default App;

This is the App.jsx file.

Code Explanation:

First of all, I imported the required Navbar, Page Components, CSS, and Hooks.

Now notice the return section of the App component. First I returned the Navbar component. That is, the navigation menu should show at the beginning of the application.

Now I have given two callback props queryData and searchBox in the Navbar component. Remember the queryData and searchBox callback methods in the code of the Navbar component in Step 1?

As defined by queryData={callFromNavbar} in the App component, the callFromNavbar function in the App component will be executed when the queryData method in the Navbar component is triggered.

Similarly searchBox={searchPage} will execute the searchPage function.

So what can do searchPage and callFromNavbar function?

When the user taps or clicks on the search box, the searchPage function redirects the URL to the search page using the useNavigate hook of the React Router.

On the other hand, when the user types something in the search box, the callFromNavbar function is responsible for receiving that data from the Navbar component and storing it in the searchQuery state variable within the App component.

Finally, I have defined the rules that will render which component to which URL through the <Route> tag.

Look in the App.jsx file above, the last <Route> tag says to render the Search component. Also, a search prop is passed to the Search component. Through this, the searchQuery state variable data is passed from the App component to the Search component.

Step 4: Show the Search Result on the Search Page

import Names from "../../assets/person.json";

function Search(props) {
  return (
    <div>
      <h1>Search from names:</h1>
      <div>
        {Names.filter((value) => {
          if (value.name == "") {
            return value;
          } else if (
            value.name
              .toLocaleLowerCase()
              .includes(props.search.toLocaleLowerCase())
          ) {
            return value;
          }
        }).map((value) => (
          <p>{value.name}</p>
        ))}
      </div>
    </div>
  );
}

export default Search;

This is the Search.jsx component file of the search page.

Code Explanation:

At the beginning of the Search component, I imported the person.json file from the assets folder. Some random people’s names are stored as key-value pairs within the JSON file.

After that, I wrote the logic to show the filtered results from the list of names with the help of an array filter. That is, if the search box is empty, then the complete list of names will show on the search page. And if any name is typed in the search box then the matched names from the list of names will show as search results.

Here props.search we can receive the data from the searchQuery state variable from the App component.

This is how you can add a search box to your React web application. And can implement basic search functionality.

Additional Resources

Above I am giving the source code of the entire project. Try to work with the source code and run your application. If you have anything difficulty understanding, read the tutorial again carefully. Or you can comment in the comment box below.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top