I have input field, which when you click, the list of fetched data shows up. Now I need to be able to search through the data based on any letter the data includes.
Example: I have list of different colors - when I type in input field letter L - all colors that has this letter gets filtered across - bLack, yeLLow, bLue, etc....
const colorInformations = "secretURL";
const [colorData, setColorData] = useState([]);
useEffect(() => {
getColorInfo();
}, []);
const getColorInfo = async () => {
try {
const response = await fetch(colorInformations);
const jsonData = await response.json();
const { array1, array2 } = jsonData;
const combinedData = array1.map(({ data1 }, i) => ({
...data1,
...array2[i].data2
}));
setColorData(combinedData);
} catch (err) {
console.log(err)
}
};
Fetched Data:
{ colorData && colorData.map(( data1, data2, index) =>
<li key={"index" + index}>
<div className="col-6 text ">
<h5>{data1.name} </h5>
<p>{data2.color} </p>
</li>
)}
For input I am trying to do this:
<input type="text" onChange={handleSearchChange} value={search} />
And handleSearchChange function:
const [search, setSearch] = useState("");
const handleSearchChange = (e) => {
setSearch(e.target.value)
}
Here I got stuck, what I need to finish is:
Filter the data based on letters - when L is typed all colors with L in are filtered
When I click on specific color it needs to be shown in input form and it has to be remembered in list - so when list is opened again the clicked color is still active
I know I should use .filter() function - I am just not sure how and where
1- add a new state for filteredData.
const [filteredColorData, setFilteredColorData] = useState([]);
2- onMount set the fetched data to the filtered data along with the actual data source.
const getColorInfo = async () => {
try {
const response = await fetch(colorInformations);
const jsonData = await response.json();
const { array1, array2 } = jsonData;
const combinedData = array1.map(({ data1 }, i) => ({
...data1,
...array2[i].data2
}));
setColorData(combinedData);
setFilteredColorData(combinedData); // set fetched Data.
} catch (err) {
console.log(err);
}
};
3- render the filtered data rather than the actual data.
{
filteredColorData && filteredColorData.map(( data1, data2, index) =>
<li key={"index" + index}>
<div className="col-6 text ">
<h5>{data1.name} </h5>
<p>{data2.suggestion} </p>
</div>
</li>
)
}
4- implement the filter functionality which filters the data and set the filtered data, and rerender it to every user input.
useEffect(() => {
filterdata();
}, [search])
const filterdata = () => {
const filtered = colorData && colorData.filter((data1) => {
return data1.name.toLowerCase().startsWith(search.toLowerCase())
})
setFilteredColorData(filtered);
}
also check this link for inspiration live working demo