I am stuck in a problem where i am implementing a search field in which a user can type into multiple field and it will give results depending on those results i.e Name, email etc.
Data object:
[
{
name:lorem,
email:[email protected]
}
]
Suppose there are two search fields one for name and other for email, and if user type in both fields or one field, it should return an array with matching properties.
i.e
searchInput ={
name:Lorem,
email:[email protected]
}
result:
[
{
name:lorem,
email:[email protected]
}
]
i am storing the input values like this
const [searchInput, setSearchInput] = useState<any>({});
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = event.target;
setSearchInput({ ...searchInput, [name]: value });
};
<input type="text" onChange={handleChange} name="email">Name</input>
I have tried multiple answer here but so far not getting the results that i want.
I have solved the search issues but now i am facing this. ******** Another Issue ********
const [users, setUsers] = useState<any>([...])
const tempArr = [...users];
const data = tempArr.filter((e: any) =>
Object.keys(e).some(
(key) =>
e[key] &&
searchInput[key] &&
e[key]
.toString()
.toLowerCase()
.includes(searchInput[key].toLowerCase())
)
);
if (data.length) {
setUsers(data);
}
so the search is working as expected but now i am losing the original data and i have to reload the page to get the original data. so is there any way to filter the data without losing the original data.
CodePudding user response:
You can try one of these:
// Ignore below
Try using useEffect
hook
useEffect(() => {
// I suppose
loadData(searchInput["email"], searchInput["name"])
}, [searchInput])
Or be more clear with the results you want
CodePudding user response:
...the search is working as expected but now I am losing the original data and I have to reload the page to get the original data.
You are losing state fidelity because you are overwriting it with the result of filtered values.
const [users, setUsers] = useState<any>([...]);
const tempArr = [...users];
const data = tempArr.filter((e: any) =>
Object.keys(e).some(
(key) =>
e[key] &&
searchInput[key] &&
e[key]
.toString()
.toLowerCase()
.includes(searchInput[key].toLowerCase())
)
);
if (data.length) {
setUsers(data); // <-- overwrites the state!!
}
So is there any way to filter the data without losing the original data.
Yes, don't overwrite the source of truth in state. Use the saved users
state array and filter state values to derive the rendered result. In other words, do the filtering inline when rendering your users
array to the UI.
Example:
users.filter((user: any) =>
Object.keys(user).some((key) =>
e[key] &&
searchInput[key] &&
e[key]
.toString()
.toLowerCase()
.includes(searchInput[key].toLowerCase()
))
).map(user => (
// ... returned JSX for `user` value
))