A Search in Another Component
Another pair of components that need the same state: a search field in SearchBox, and the lineup in BandList. As you type, the list should show only the bands that match. Right now, the field is controlled by state in SearchBox, and BandList can't see it. It's the same situation as with the favorites, so it has the same solution: search goes up to App, their closest common parent.
SearchBox then gets the text and a function to call with the new text. Its field stays controlled, only now by state that lives in App:
export default function SearchBox({ search, onSearchChange }) {
return (
<input
className="search"
placeholder="Search for a band"
value={search}
onChange={(event) => onSearchChange(event.target.value)}
/>
);
}App keeps the state and passes it down, together with its setter: <SearchBox search={search} onSearchChange={setSearch} />. setSearch is a function like any other, so it can be passed down as it is: when the field changes, SearchBox calls onSearchChange with the new text, and that's setSearch of App.
And the filtered list? It's computed from bands and search, so it isn't state either. App filters the bands while rendering, and passes BandList only those it should show. Here's the same idea with a filter by day:
const shownBands = bands.filter((band) => band.day === day);To ignore capital letters in the search, compare both texts in lowercase, with toLowerCase() from the JavaScript course: "Night Trains".toLowerCase() is "night trains".
Instructions
Move search up into App, and pass it to SearchBox with a function onSearchChange. Give BandList only the bands whose name contains the search text, ignoring capital letters: NIGHT finds Night Trains.
When no band matches, show No band matches your search. in a paragraph with the class empty.