i have an array of objects containing users data stored in a state varaible
and a table where I am displaying these users. I have a search field where a user can type name and search. Now my question is when a user types i want to search from these names and update the state variable and when user clears the input ,that time i want to show all users.in simple terms a search functionality.
const searchUsers = () => {
items.filter((item) => {
if (searchTerm === null) {
setItems([...items]);
return item;
} else if (item.title.toLowerCase().includes(searchTerm)) {
setItems([item]);
}
});
};
CodePudding user response:
You can try useMemo hook for this. You dont even need to update the state for filtered results.
const searchResults = useMemo(() => {
if (!searchTerm) {
return items;
}
return items?.filter((item) =>
item?.toLowerCase()?.includes(searchTerm?.toLowerCase().trim())
);
}, [items, searchTerm]);
You can directly use the searchResults
while rendering your table.
CodePudding user response:
Try this:
const searchUsers = () => {
if (searchTerm === "" || searchTerm === null) {
setItems([...items])
return
}
const results = items.filter((item) => item.title.toLowerCase().includes(searchTerm))
setItems(results)
}
- If
searchTerm
is empty return all items and stop search - If
searchTerm
is not empty filter items based onsearchTerm
- Set the
results
as items
What you have to ensure as well is that setItems
is not the setter for items
. If you filter you will "remove" the items from the list which will cause elements to disappear when users searches something and goes back to an empty / or another search term. To fix this separate the state where all items are in and the state which items to display or filter in the JSX part.
The code could look like this:
const items = ...
const [filteredItems, setFilteredItems] = setState(items)
const searchUsers = () => {
if (searchTerm === "" || searchTerm === null) {
setFilteredItems([...items])
return
}
const results = items.filter((item) => item.title.toLowerCase().includes(searchTerm))
setFilteredItems(results)
}
return {filteredItems.map(item => <p>{item.title}</p>)}
CodePudding user response:
var defaultitems = useMemo(_=>items)
const searchUsers = () => {
if(!searchTerm) return setItems(defaultitems)
var filtered = items.filter((item) => {
if (item.title.toLowerCase().includes(searchTerm)) {
return true
}
return false
});
setItems(filtered)
};