I want to create a filtering function that trigger when receiving a input value event in react useState but i do not see is doing anything when I start typing in. This is my Search component
export function Search({categories, onSearch}){
const [searchText, setSearchText] = useState('');
const filterCategories = () => {
const filteredCategories = categories.filter(category =>
category.name.toLowerCase().includes(searchText.toLowerCase())
);
onSearch(filteredCategories);
};
const handleInputChange = event => {
setSearchText(event.target.value);
filterCategories();
};
return (
<div className="flex items-center">
<form className='flex space-x-1' >
<input
type="text"
className="block w-full px-4 py-2 text-purple-700 bg-white border rounded-full focus:border-purple-400 focus:ring-purple-300 focus:outline-none focus:ring focus:ring-opacity-40"
placeholder="Search..."
value={searchText}
onChange={handleInputChange}
/>
</form>
</div>
)
}
Then is being used here
const Layout = ({ categories, children }) => {
const [filteredCategories, setFilteredCategories] = useState(categories);
const handleSearch = (filteredCategories) => {
setFilteredCategories(filteredCategories);
};
return (
<div>
{/* ... */}
<Search categories={categories} onSearch={handleSearch} />
{/* ... */}
{children}
</div>
);
};
export default Layout;
and That goes into the Home component
export default function Home({ posts, categories }) {
return (
<Layout categories={categories}>
<div className="mt-20">
<main className="flex flex-col justify-center items-center h-screen pt-10 pb-30">
{/* Render posts */}
</main>
</div>
</Layout>
);
}
Is there anything I should do to make this work?
3
Answers
In the Layout component you are passing
categories
value to your Search component, you probably meant to passfilteredCategories
(
filteredCategories
was unused which made you feel that nothings was happening)Your code seems correct. Ensure categories have valid data with name property. To debug, add console.log in handleInputChange and filterCategories to see if they’re triggered and check the console for issues. If the input change and filtering events are working, it might be a styling or UI issue. Look at my code bellow i updated
your
handleSearch
function passed as propsonSearch
toSearch
component expects an argfilteredCategories
to set it to its statefilteredCategories
.Now you are calling it each time you type in the input:
what it does ?
so you filtter based on
searchText
then you callonSearch
passing the result of your filter i.efilteredCategories
, however, this is not the correct approach sincesearchText
won’t be updated immediately but when the component rerenders (so you are a step late), therefore, you have to filter based on the input value not the state, in fact, with your implementation, you don’t even need thesearchText
state at all:Now you have the correct logic to update
filteredCategories
state in the parent component (Layout
) and you should see the expected filtred data logged each time you type in the child component input causing the layout component to rerender: