I have the following code:
import SearchBar from "material-ui-search-bar";
const data = [
{
name: "Jane"
},
{
name: "Mark"
},
{
name: "Jason"
}
];
export default function App() {
const [results, setResults] = useState();
const filteredResults = data.filter((item) => {
return Object.keys(item)?.some((key) => {
return item[key].includes(results?.toLowerCase());
});
});
return (
<div className="App">
<SearchBar
value={results}
onChange={(value) => setResults(value)}
placeholder="Please enter name..."
/>
{filteredResults.map((item) => {
return <li>{item.name}</li>;
})}
</div>
);
}
when I delete name from search bar using delete keyboard all names from data are displayed below the search bar, but if I click X button, it clears the search bar but doesn't display all names. Is there a way to add a function to this X button so when I click it, it acts the same way as delete keyboard?
You can pass a function to the onCancelSearch
prop to reset the results
state variable.
<SearchBar
value={results}
onChange={(value) => setResults(value)}
onCancelSearch={() => setResults('')}
/>
It's better to initialize results
with an empty string. You can now remove the ?
in results?.toLowerCase()
since results
will never be nullish (undefined
or null
).
const [results, setResults] = useState('')
You should pass the key
prop to the li
element. You can add an id
property to the items array to use as the key or use the item index.
{
filteredResults.map((item) => (
<li key={item.id}>{item.name}</li>
))
}
And there are a couple of issues with the filtering logic.
You're converting the search query to lowercase but not the name. In your example, if you search for 'ja'
, nothing would show up even though matches exist (Jane and Jason).
filteredResults
will throw an error if any of the object values do not have the includes
method (You can reproduce the issue by adding a numeric id
field to the array items). You could fix it by using a searchableKeys
array to only perform the search in specific fields.
const searchableKeys = ['name']
const filteredResults = data.filter((item) =>
searchableKeys.some((key) =>
item[key].toLowerCase().includes(results.toLowerCase())
)
)
I would recommend renaming results
to query
or searchQuery
for clarity.