I have an autocomplete input field and running into issues when initially hiding the output in my array. Instead of showing all my items when mounted, I just want to show the matching string. Leaving my state empty const [filteredRecipes, setFilteredRecipes] = useState();
will throw in error in my loop.
Codesanbox: https://codesandbox.io/s/quzwg?file=/App.js:251-313
Js:
export default function App() {
const items = useMemo(
() => ["item1", "item2", "anotheritem", "yetanotheritem", "myitem"],
[]
);
const [search, setSearch] = useState("");
const [filteredRecipes, setFilteredRecipes] = useState(items);
const handleSearchChange = event => {
setSearch(event.target.value);
};
useEffect(() => {
setFilteredRecipes(
items.filter(el => el.toLowerCase().includes(search.toLowerCase()))
);
}, [search, items]);
return (
<div>
<input
type="search"
placeholder="type here to filter"
value={search}
onChange={handleSearchChange}
/>
<div>
{filteredRecipes.map(recipe => (
<p>{recipe}</p>
))}
</div>
</div>
);
}
If I'm understanding your question correctly, in your example filteredRecipes
are the autocomplete suggestions that you want to initially hide when mounting, or, making an assumption here, whenever the search value is falsey. You can do this by conditionally filtering on search
state being truthy/falsey. All strings will include the empty string (''
), so you want to handle this case differently.
setFilteredRecipes(
search
? items.filter((el) => el.toLowerCase().includes(search.toLowerCase()))
: []
);
Code
export default function App() {
const items = useMemo(
() => ["item1", "item2", "anotheritem", "yetanotheritem", "myitem"],
[]
);
const [search, setSearch] = useState("");
const [filteredRecipes, setFilteredRecipes] = useState([]);
const handleSearchChange = (event) => {
setSearch(event.target.value);
};
useEffect(() => {
setFilteredRecipes(
search
? items.filter((el) => el.toLowerCase().includes(search.toLowerCase()))
: []
);
}, [search, items]);
return (
<div>
<input
type="search"
placeholder="type here to filter"
value={search}
onChange={handleSearchChange}
/>
<div>
{filteredRecipes.map((recipe) => (
<p>{recipe}</p>
))}
</div>
</div>
);
}