Type to generate UI components from text

OR

Browse thousands of MUI, Tailwind, React components that are fully customizable and responsive.

Explore Components

A Complete Guide on How to Create an MUI Search Bar in React

A search bar is a user interface element we commonly find in websites, applications, and other digital platforms. It serves as a text input field where users can enter keywords, phrases, or queries to initiate a search for specific information within the system. The primary purpose of a search bar is to facilitate the quick and targeted retrieval of content or data from a larger set of information.

Building a React search bar with suggestions may appear challenging for React beginners. However, several React libraries simplify the process and enable you to construct one efficiently.

In this article, I’ll walk you through the steps to create a fully functional React search bar with suggestions in React. But, before delving into the implementation, let’s explore some of the common use cases for search bars.

PS: Engineers waste time building and styling components when working on a project, writing repetitive markup adds time to the project and is a mundane, boring task for engineers. PureCode.ai uses AI to generate a large selection of custom, styled UI components for different projects and component types.

Real-World Examples of Search Bars

Search bars are integral components of web development, serving a multitude of purposes across diverse websites and applications. Their pervasive presence elevates user experience by swiftly providing efficient access to specific information. The versatility of search bars is evident in various real-world use cases:

  • E-commerce Websites: In the realm of e-commerce, search bars streamline product discovery. Users effortlessly locate desired items through keyword searches, category filters, and sorting options based on attributes such as price and brand.

    Amazon Search Bar - Marketplace Pulse
  • Content Platforms: For content-centric websites, search bars empower users to find specific articles, blog posts, images, videos, or audio content. This functionality enhances content retrieval and exploration.

    YouTube Search Bar
  • Social Media Platforms: On social media platforms, search bars are pivotal for user interaction with which users can navigate profiles, find friends, or discover specific content, fostering a dynamic and engaging environment.

    LinkedIn Search Bar

Prerequisites for Creating React Material UI Search Bar

Before diving into the tutorial on creating a React Material UI Search Bar, ensure that you have the following prerequisites in place on your computer:

  1. Node, npm, and create-react-app Installed: Make sure you have Node.js and npm (Node Package Manager) installed.

  2. Basic Knowledge of JavaScript and React.js: Familiarity with JavaScript and the React.js library is essential to grasp the concepts covered in this tutorial effectively.

By confirming these prerequisites, you’ll be well-prepared to follow along and implement the React Material UI Search Bar successfully.

Step By Step Guide to Creating a React Search Bar using MUI

In this article, I will guide you through the process of building a search bar with autosuggestion from scratch using Material UI. Before incorporating the autosuggestion feature, we’ll first construct a basic search bar. This initial step aims to provide clarity for later comparison between the two search bars in subsequent sections of the article.

The tutorial includes the following sections:

  1. Creating a Search Bar Using MUI TextField Component: Learn how to create a fundamental search bar using the Material UI TextField component.

  2. Creating a Search Bar Using MUI Autocomplete Component: Progress to implementing the autosuggestion feature by building a search bar with the Material UI Autocomplete component.

By following these steps, you’ll gain a comprehensive understanding of both search bar implementations, setting the stage for effective comparison and analysis later in the article.

Create a new React App Project

Begin by creating a new folder in VS Code. In the terminal, enter the following code to generate a fresh React app:

npx create-react-app react-search-bar

Next, navigate to the newly created React app and streamline the project by removing unnecessary files. With these preparations complete, you are now ready to proceed with building the search bar.

Install Material UI, Material Icons and Axios

After creating the new React project, next, you need to install three essential libraries:

Run the following code in the root folder of your app, this installation process is crucial for integrating the desired functionalities into your project:

npm i axios @mui/material @emotion/react @emotion/styled @mui/icons-material

Wait for the installation process to complete, ensuring that your project is equipped with the necessary dependencies for Material UI components, icons, and Axios functionality.

Creating a Search Bar Using MUI TextField Component

To create a Search Bar using the MUI TextField component, let’s start by organizing the project structure. Create a `components` folder within the `src` directory. Inside this folder, initiate a new file named `TextFieldSearchBar.jsx` for the React search bar component.

Next, copy and paste the provided code into `TextFieldSearchBar.jsx`. This code utilizes Material UI components and includes a search bar with a corresponding button. As a result, we style and position the search bar within a container for an organized layout.

import { useState } from "react";
import { Box, IconButton, TextField, Typography } from "@mui/material";
import SearchIcon from "@mui/icons-material/Search";
import FilterProducts from "./FilterProducts";

const TextFieldSearchBar = ({ list }) => {
  return (
    <Box
      className="App"
      sx={{
        width: 400,
        height: 660,
        margin: "100px auto",

        display: "flex",
        flexDirection: "column",
        justifyContent: "space-evenly"
      }}
    >
      <Typography variant="h4" component={"h1"}>
        MUI TextField Search Bar
      </Typography>

      <form style={{ display: "flex", alignItems: "center" }}>
        <TextField
          id="search-bar"
          className="text"
          label="Search title"
          variant="outlined"
          placeholder="Search..."
          size="small"
          sx={{
            width: 350,
            margin: "10px auto"
          }}
        />
        <IconButton type="submit" aria-label="search">
          <SearchIcon style={{ fill: "blue" }} />
        </IconButton>
      </form>

      <FilterProducts searchstring={input} list={list} />
    </Box>
  );
};

export default TextFieldSearchBar;

Note that the component imports `FilterProducts` for implementing the search logic. The step-by-step details for this logic will be covered later.

Now, you have a foundational search bar component ready for use. In the subsequent sections, we’ll delve into the logic behind the search. For now, let’s integrate dummy product data for testing purposes.

Getting Dummy Product Data

To integrate dummy product data into your application, start by creating a new file in the `src` folder named `fetchData.js`. This file will utilize the dummyJSON API to fetch dummy product data, and you can use the following code snippet:

import axios from 'axios'

export const fetchData = async ()=>{
   try{
       const response = await axios.get('https://dummyjson.com/products')
       return response.data.products
    }
    catch (error) {
       console.log(error);
   }
}

Having set up the data-fetching mechanism, proceed to your `App.js` file. Import the `fetchData` function and use the `useEffect` and `useState` hooks to manage the fetched data. Create a list constant to store the data, and pass this list as a prop to the `FilterProducts` component through the `TextFieldSearchBar` component. Here’s how you can structure your `App.js`:

import { useEffect, useState } from "react";
import { fetchData } from "./fetchData";
import TextFieldSearchBar from "./components/TextFieldSearchBar";
import "./App.css";

function App() {
  const [list, setList] = useState([]);

  useEffect(() => {
    fetchData().then((res) => setList(res));
  }, []);

  return (
    <>
      <TextFieldSearchBar list={list} />
    </>
  );
}

export default App;

With these steps, your React application is now equipped with dummy product data fetched from the specified API. The `TextFieldSearchBar` component can efficiently utilize this data for implementing effective search functionality in your application.

Getting User Input

To capture user input effectively in the `TextFieldSearchBar` component, implement the following enhancements:

import { useState } from "react";
import { Box, IconButton, TextField, Typography } from "@mui/material";
import SearchIcon from "@mui/icons-material/Search";
import FilterProducts from "./FilterProducts";

const TextFieldSearchBar = ({ list }) => {
  const [input, setInput] = useState("");

  const handleInput = (e) => {
    console.log(e.target.value);
    setInput(e.target.value.toLowerCase());
  };

  return (
    <Box
      className="App"
      sx={{
        width: 400,
        height: 660,
        margin: "100px auto",

        display: "flex",
        flexDirection: "column",
        justifyContent: "space-evenly"
      }}
    >
      <Typography variant="h4" component={"h1"}>
        MUI TextField Search Bar
      </Typography>

      <form style={{ display: "flex", alignItems: "center" }}>
        <TextField
          id="search-bar"
          className="text"
          onInput={handleInput}
          label="Search title"
          variant="outlined"
          placeholder="Search..."
          size="small"
          sx={{
            width: 350,
            margin: "10px auto"
          }}
        />
        <IconButton type="submit" aria-label="search">
          <SearchIcon style={{ fill: "blue" }} />
        </IconButton>
      </form>

      <FilterProducts searchstring={input} list={list} />
    </Box>
  );
};

export default TextFieldSearchBar;

In this optimized version, the `handleInput` function updates the `input` state directly with the lowercase value of the user’s input. This streamlined approach efficiently stores user input as a constant, ensuring that it can be easily passed down as a prop to the `FilterProducts` component.

Filtering Through Search Results

Finally, let’s create the `FilterProducts` component. Create a `FilterProducts.jsx` file in the `components` folder that was created inside the `src` folder. Utilize the array filter function to filter dummy data based on the search input.

import { Stack } from "@mui/system";
import { Paper, Box, Typography } from "@mui/material";

/**
 * Component to filter and display products based on search input.
 * @param {string} searchstring - The search string to filter products.
 * @param {Array} list - The array of products to filter.
 * @returns {JSX.Element} - The filtered product list.
 */
export default function FetchProducts({ searchstring, list }) {
  // Create a new array, filteredList, using the array filter function to filter the dummy data based on input.
  const filteredList = list.filter((element) => {
    if (searchstring === "") {
      return element;
    } else {
      return element.title.toLowerCase().includes(searchstring);
    }
  });

  // Display the filtered product list.
  return (
    <Box>
      <Stack
        spacing={2}
        sx={{
          overflow: "auto",
          maxHeight: 500
        }}
      >
        {filteredList.map((item) => (
          <Paper
            key={item.id}
            sx={{
              textAlign: "left"
            }}
          >
            <Typography>
              <strong>Title:</strong> {item.title}
            </Typography>
            <Typography>
              <strong>Desc:</strong> {item.description}
            </Typography>
            <Typography>
              <strong>Price:</strong> {item.price}
            </Typography>
            <Typography>
              <strong>Rating:</strong> {item.rating}
            </Typography>
            <Typography>
              <strong>Brand:</strong> {item.brand}
            </Typography>
          </Paper>
        ))}
      </Stack>
    </Box>
  );
}

This code defines a React component named `FetchProducts` that is responsible for filtering and displaying a list of products based on a search string. The component takes two props: `searchstring` (the search string used for filtering) and `list` (an array of products to filter).

The `filteredList` is created using the filter method on the list array. It checks whether each element’s title, converted to lowercase, includes the `searchstring`. If `searchstring` is empty, the original list is returned.

The component returns a JSX structure using Material-UI components. It utilizes a `Stack` component for vertical stacking of product cards and a `Paper` component for each product’s card.

Creating a Search Bar With MUI Autocomplete Component

We’ve seen how to create a search bar without the auto-suggestion feature, let’s see how one can be built with the auto-suggestion feature using the Autocomplete component in Material UI. We need to create a new component for this search bar and create a new file called `AutocompleteSearchBar.jsx` inside the components folder.

The `AutocompleteSearchBar` component is designed to provide an interactive search experience with auto-suggestion functionality using Material-UI’s Autocomplete component. Let’s break down the key aspects of the code.

The component begins by managing the state using the `useState` hook:

const [input, setInput] = useState("");

Here, the `input` state variable is employed to track the user’s input as they interact with the search bar.

The input handling is facilitated through the `handleInput` function:

const handleInput = (e) => {
  console.log(e.target.value);
  setInput(e.target.value.toLowerCase());
};

This event handler, attached to the Autocomplete component, logs the user’s input to the console and updates the `input` state with the lowercase version of the input.

How to Implement Autocomplete

The core of the Autocomplete functionality is implemented through the Autocomplete component itself:

<Autocomplete
  disablePortal
  id="combo-box-demo"
  options={list.map((item) => item.title)}
  renderInput={(params) => (
    <TextField
      {...params}
      label="Search title"
      onSelect={handleInput}
      sx={{
        width: 350,
        margin: "10px auto"
      }}
    />
  )}
/>

Configured with specific properties, such as `disablePortal`, `id`, and `options`, this component provides users with autocomplete suggestions based on the titles extracted from the `list` prop. The input field is rendered using the TextField component, and the `onSelect` event triggers the `handleInput` function.

The AutocompleteSearchBar component concludes by rendering the `FilterProducts` component:

<FilterProducts searchstring={input} list={list} />

This component likely handles the filtering logic based on the user’s input, displaying the filtered results.

Finally, the entire component is encapsulated within a Box component, employing specified styles for width, height, margin, and flex layout. This ensures a visually appealing and responsive layout for the search bar.

import { useState } from "react";
import { Typography, Box, TextField, Autocomplete } from "@mui/material";
import FilterProducts from "./FilterProducts";

function AutocompleteSearchBar({ list }) {
  const [input, setInput] = useState("");

  const handleInput = (e) => {
    console.log(e.target.value);
    setInput(e.target.value.toLowerCase());
  };

  return (
    <Box
      className="App"
      sx={{
        width: 400,
        height: 660,
        margin: "100px auto",

        display: "flex",
        flexDirection: "column",
        justifyContent: "space-evenly"
      }}
    >
      <Typography variant="h4" component={"h1"}>
        MUI Autocomplete Search Bar
      </Typography>
      <Autocomplete
        disablePortal
        id="combo-box-demo"
        options={list.map((item) => item.title)}
        renderInput={(params) => (
          <TextField
            {...params}
            label="Search title"
            onSelect={handleInput}
            sx={{
              width: 350,
              margin: "10px auto"
            }}
          />
        )}
      />

      <FilterProducts searchstring={input} list={list} />
    </Box>
  );
}

export default AutocompleteSearchBar;

In summary, the AutocompleteSearchBar component seamlessly integrates Material-UI’s Autocomplete component, providing users with a polished and user-friendly search experience. The code structure emphasizes readability and maintainability, making it easy to understand and extend.

With PureCode.ai you can get customized, and ready-to-use components which will allow you to prioritize more important and thought-intensive tasks to speed up the development of your user interface. PureCode.ai can cater to your code development process, saving you valuable time and effort when working on a project.

Creating a Tab to View Both Search Bars

Now, that we have both search bars built – one without auto-suggestion and another with auto-suggestion, let’s create a tab so we can easily switch between both search bars.

In order to create this tab we need to refactor the `App` component to orchestrate the integration of two distinct search bars, one based on a traditional TextField and the other employing Material-UI’s Autocomplete. Below is an explanation of the key components and functionalities:

Let’s start by making sure all the necessary dependencies and styling are imported to the `App` component:

import { useEffect, useState } from "react";
import { Box, ToggleButtonGroup, ToggleButton } from "@mui/material";
import { fetchData } from "./fetchData";
import TextFieldSearchBar from "./components/TextFieldSearchBar";
import AutocompleteSearchBar from "./components/AutocompleteSearchBar";
import "./App.css";

Next, we want to manage state by using the `useState` hook, establishing variables for the currently selected tab (`tab`) and the list of products (`list`):

const [tab, setTab] = useState("textField");
const [list, setList] = useState([]);

Once that’s done, we want to fetch data when the component mounts and updates the `list` state using the `useEffect` hook:

useEffect(() => {
  fetchData().then((res) => setList(res));
}, []);

Next, we need to create a function to that the tabs. The `handleTab` function manages the state when the user switches between tabs in the ToggleButtonGroup:

const handleTab = (event, newTab) => {
  setTab(newTab);
};

The component renders a ToggleButtonGroup to toggle between the two search bars:

<Box
  className="App"
  sx={{
    width: 400,
    margin: "25px auto 5px",
    display: "flex",
    justifyContent: "space-evenly"
  }}
>
  <ToggleButtonGroup
    value={tab}
    exclusive
    onChange={handleTab}
    aria-label="tab switch"
  >
    <ToggleButton value="textField" aria-label="Text Field">
      Text Field
    </ToggleButton>
    <ToggleButton value="autocomplete" aria-label="Autocomplete">
      Autocomplete
    </ToggleButton>
  </ToggleButtonGroup>
</Box>

The conditional rendering section renders either the `TextFieldSearchBar` or `AutocompleteSearchBar` based on the selected tab:

{tab === "textField" ? (
  <TextFieldSearchBar list={list} />
) : (
  <AutocompleteSearchBar list={list} />
)}

Final Result

In summary, the `App` component serves as the main controller, allowing users to seamlessly switch between traditional text-based search and autocomplete search functionalities. The code structure emphasizes modularity and clarity, making it easy to understand and extend.

import { useEffect, useState } from "react";
import { Box, ToggleButtonGroup, ToggleButton } from "@mui/material";
import { fetchData } from "./fetchData";
import TextFieldSearchBar from "./components/TextFieldSearchBar";
import AutocompleteSearchBar from "./components/AutocompleteSearchBar";
import "./App.css";

function App() {
  const [tab, setTab] = useState("textField");
  const [list, setList] = useState([]);

  useEffect(() => {
    fetchData().then((res) => setList(res));
  }, []);

  const handleTab = (event, newTab) => {
    setTab(newTab);
  };

  return (
    <>
      <Box
        className="App"
        sx={{
          width: 400,
          margin: "25px auto 5px",

          display: "flex",
          justifyContent: "space-evenly"
        }}
      >
        <ToggleButtonGroup
          value={tab}
          exclusive
          onChange={handleTab}
          aria-label="tab switch"
        >
          <ToggleButton value="textField" aria-label="Text Field">
            Text Field
          </ToggleButton>
          <ToggleButton value="autocomplete" aria-label="Autocomplete">
            Autocomplete
          </ToggleButton>
        </ToggleButtonGroup>
      </Box>

      {tab === "textField" ? (
        <TextFieldSearchBar list={list} />
      ) : (
        <AutocompleteSearchBar list={list} />
      )}
    </>
  );
}

export default App;

Here’s how the application would look when viewed on the browser with `textField` as the selected tab:

TextField Seach Bar

When `autocomplete` is selected as the tab, this is what it’ll look like:

Autocomplete Search Bar

The Difference Between Building a Search Bar with the TextField Component and the Autocomplete Component in Material UI

FeatureTextField ComponentAutocomplete Component
Basic FunctionalityBasic text inputSuggestions and autocomplete functionality
CustomizationCustomizable for various use casesEnhanced styling with dropdown for suggestions
Input HandlingManual handling of user input eventsBuilt-in handling of user input and suggestions
Filtering LogicRequires manual implementationBuilt-in filtering based on user input
Direct User InputWell-suited for direct user inputProvides a dropdown for selecting suggestions
API IntegrationTypically used for static input scenariosWell-suited for dynamic suggestions from APIs
Enhanced UXSimple input fieldEnhanced user experience with a suggestion list
FreeSolo ModeNo built-in supportSupports free-form input with freeSolo mode
Rendering CustomizationCustomizable but with more effortProvides flexibility in rendering suggestions

Final Thoughts on MUI Search Bar

Now that we’ve learnt how to build search bars with and without auto-suggestions, how then do you know when to use each. Let’s a take a quick look at when they can be useful:

  • Use TextField:

    • When you need a simple text input without suggestions.

    • In scenarios where you want full control over input handling and don’t require autocomplete features.

  • Use Autocomplete:

    • When you want to provide users with suggestions or autocomplete functionality.

    • In scenarios where you have a predefined list of options or want to fetch suggestions dynamically from an external source.

In conclusion, the choice between the TextField and Autocomplete components depends on the specific requirements of your search functionality and the desired user experience. The Autocomplete component is particularly powerful when suggestions and autocompletion are key features of your search bar.

The complete code used for this tutorial is made available on code sandbox.

Further Readings

If you enjoyed reading this piece, consider reading other articles from our blogs and also, my recommendations:

For your reference, you can also check out the below YouTube video to learn more about the Material UI search bar.

Shadrach Abba

Shadrach Abba