Back to Blog
Lesson 15 of the React Fundamentals: Build Modern UIs from Scratch course
ReactJune 25, 20263 min read

Building an Interactive Search Bar: Controlled Inputs in React

Learn to build an interactive search bar in React. Master controlled inputs by synchronizing form values with local state for a reactive, responsive UI.

reactjavascriptfrontendhooksformsweb development

Previously in this course, we explored introduction to react state: making your ui interactive and mastered managing state with usestate: a beginner's guide to react hooks. In this lesson, we apply those fundamentals to build a functional search bar, moving from static HTML to dynamic, data-driven inputs.

The Concept: Controlled Inputs

In standard HTML, an <input> field maintains its own internal state. When a user types, the browser automatically updates the display. However, in React, we prefer the "Single Source of Truth" pattern.

We achieve this using controlled inputs. A controlled input is a form element whose value is driven by React state rather than the browser's internal DOM state. When the user types, we capture the event, update our state, and React re-renders the component to display the new value.

This approach gives us full control over the data, allowing us to validate, transform, or log input in real-time.

Building the Search Bar

To build our search bar, we need two things: an input element and a piece of state to track what the user is typing. We’ll use the onChange event listener to trigger a state update every time a key is pressed.

Here is how you implement it in your SearchBar component:

JSX
import { useState } from CE9178">'react';

function SearchBar() {
  const [searchTerm, setSearchTerm] = useState(CE9178">'');

  const handleChange = (event) => {
    const newValue = event.target.value;
    setSearchTerm(newValue);
    
    // Logging state changes to the console
    console.log("Current search term:", newValue);
  };

  return (
    <div className="search-container">
      <input
        type="text"
        placeholder="Search for movies..."
        value={searchTerm}
        onChange={handleChange}
      />
      <p>Searching for: {searchTerm}</p>
    </div>
  );
}

export default SearchBar;

Breaking down the code:

  1. useState(''): We initialize our state with an empty string. This represents the starting value of the search bar.
  2. value={searchTerm}: This is the "controlled" part. We tell the input that its value must always match the searchTerm state variable.
  3. onChange={handleChange}: Whenever the user types, the browser fires an event. We access event.target.value to get the current characters in the box and update our state.

Hands-on Exercise

It's time to advance our movie-browser project. Follow these steps:

  1. Create a new file named SearchBar.jsx in your components folder.
  2. Implement the code above, ensuring you import useState from React.
  3. Add this component to your main App.jsx file to see it in action.
  4. Open your browser's Developer Tools (F12) and go to the "Console" tab. Type into the input field and confirm that every keystroke logs the updated state correctly.

Common Pitfalls

Even experienced developers run into these issues when starting with forms:

  • Forgetting the onChange handler: If you provide a value prop to an input but don't provide an onChange handler, the input will become read-only. You won't be able to type anything!
  • Assuming State is Synchronous: Remember that calling setSearchTerm does not update the variable immediately in the current execution context. If you console.log(searchTerm) immediately after setting it, you will see the old value. Always use the event object (event.target.value) if you need the immediate new value.
  • Over-complicating state: For a simple search bar, you don't need complex patterns. Keep it simple with useState until you reach the requirements of react form handling: controlled vs. uncontrolled components.

Recap

By controlling our input, we've bridged the gap between user interaction and application state. We've learned that:

  • Controlled inputs allow React to own the data within a form field.
  • The value prop links the input to our useState variable.
  • The onChange event is the primary mechanism for capturing user input.

You now have a responsive search bar that tracks user intent. This component is the foundation for the filtering logic we will build in upcoming lessons.

Up next: We will explore Handling Click Events to make our application even more interactive.

Similar Posts