SearchBar
The SearchBar component provides a controlled text input for searching movies by title, director, or actor. It’s a simple, reusable component that delegates state management to its parent.
Component Overview
import SearchBar from './components/SearchBar' ;
import { useState } from 'react' ;
function App () {
const [ searchTerm , setSearchTerm ] = useState ( '' );
return (
< SearchBar
searchTerm = { searchTerm }
onSearchChange = { setSearchTerm }
/>
);
}
Props
Current value of the search input. This is a controlled component, so the parent must manage this state.
Callback function invoked when the input value changes. Signature : (newValue: string) => voidParameters :
newValue - The new search term entered by the user
Features
Controlled Component Pattern
The SearchBar follows React’s controlled component pattern:
const SearchBar = ({ searchTerm , onSearchChange }) => {
return (
< input
type = "text"
value = { searchTerm }
onChange = { ( e ) => onSearchChange ( e . target . value ) }
/>
);
};
The parent component owns the state, making it easy to:
Sync with other filters
Persist to URL parameters
Reset or clear programmatically
Search Icon
Includes a visual search icon for better UX:
< span className = "search-bar__icon" > 🔍 </ span >
Placeholder Text
Descriptive placeholder guides users:
placeholder = "Buscar películas por título, director o actor..."
Usage Examples
Basic Search
import { useState } from 'react' ;
import SearchBar from './components/SearchBar' ;
function SearchExample () {
const [ searchTerm , setSearchTerm ] = useState ( '' );
return (
< div >
< SearchBar
searchTerm = { searchTerm }
onSearchChange = { setSearchTerm }
/>
< p > Searching for: { searchTerm } </ p >
</ div >
);
}
With Movie Filtering
import { useState , useMemo } from 'react' ;
import SearchBar from './components/SearchBar' ;
import PeliculaGrid from './components/PeliculaGrid' ;
function PeliculasPage ({ peliculas }) {
const [ searchTerm , setSearchTerm ] = useState ( '' );
const filteredPeliculas = useMemo (() => {
if ( ! searchTerm ) return peliculas ;
const lowerSearch = searchTerm . toLowerCase ();
return peliculas . filter ( p =>
p . title . toLowerCase (). includes ( lowerSearch ) ||
p . director . toLowerCase (). includes ( lowerSearch ) ||
p . cast . some ( actor => actor . toLowerCase (). includes ( lowerSearch ))
);
}, [ peliculas , searchTerm ]);
return (
< div >
< SearchBar
searchTerm = { searchTerm }
onSearchChange = { setSearchTerm }
/>
< PeliculaGrid peliculas = { filteredPeliculas } loading = { false } />
</ div >
);
}
In Real Application
From src/pages/PeliculasPage.jsx:23:
import PeliculaGrid from '../components/PeliculaGrid' ;
import SearchBar from '../components/SearchBar' ;
import CategoryFilter from '../components/CategoryFilter' ;
import usePeliculaSearch from '../hooks/usePeliculaSearch' ;
const PeliculasPage = () => {
const {
searchTerm ,
setSearchTerm ,
selectedCategory ,
setSelectedCategory ,
filteredPeliculas ,
loading ,
categories
} = usePeliculaSearch ();
return (
< div className = "peliculas-page" >
< h1 className = "peliculas-page__title" > Catálogo de Películas </ h1 >
< div className = "peliculas-page__filters" >
< SearchBar
searchTerm = { searchTerm }
onSearchChange = { setSearchTerm }
/>
< CategoryFilter
categories = { categories }
selectedCategory = { selectedCategory }
onCategoryChange = { setSelectedCategory }
/>
</ div >
< p className = "peliculas-page__results" >
{ filteredPeliculas . length } películas encontradas
</ p >
< PeliculaGrid peliculas = { filteredPeliculas } loading = { loading } />
</ div >
);
};
Full Component Code
Location: src/components/SearchBar.jsx:1
import React from 'react' ;
const SearchBar = ({ searchTerm , onSearchChange }) => {
return (
< div className = "search-bar" >
< input
type = "text"
className = "search-bar__input"
placeholder = "Buscar películas por título, director o actor..."
value = { searchTerm }
onChange = { ( e ) => onSearchChange ( e . target . value ) }
/>
< span className = "search-bar__icon" > 🔍 </ span >
</ div >
);
};
export default SearchBar ;
Accessibility
Keyboard Support
The input supports standard keyboard interactions:
Type to search
Tab to navigate
Escape to clear (with custom handler)
Adding Labels
For better accessibility, add an associated label:
< label htmlFor = "movie-search" className = "sr-only" >
Search movies
</ label >
< SearchBar
id = "movie-search"
searchTerm = { searchTerm }
onSearchChange = { setSearchTerm }
/>
Styling
The component uses these BEM classes:
.search-bar - Main container
.search-bar__input - Text input element
.search-bar__icon - Search icon
Custom Enhancements
Debounced Search
To avoid excessive filtering on every keystroke:
import { useState , useEffect } from 'react' ;
import { useDebounce } from './hooks/useDebounce' ;
function DebouncedSearch () {
const [ searchTerm , setSearchTerm ] = useState ( '' );
const debouncedSearch = useDebounce ( searchTerm , 300 );
useEffect (() => {
// Perform search with debouncedSearch
}, [ debouncedSearch ]);
return (
< SearchBar
searchTerm = { searchTerm }
onSearchChange = { setSearchTerm }
/>
);
}
Add a button to clear the search:
function SearchWithClear () {
const [ searchTerm , setSearchTerm ] = useState ( '' );
return (
< div className = "search-container" >
< SearchBar
searchTerm = { searchTerm }
onSearchChange = { setSearchTerm }
/>
{ searchTerm && (
< button onClick = { () => setSearchTerm ( '' ) } >
Clear
</ button >
) }
</ div >
);
}
CategoryFilter Often used alongside SearchBar for combined filtering
PeliculaGrid Displays filtered search results