Estoy atascado en un problema en el que estoy implementando un campo de búsqueda en el que un usuario puede escribir en varios campos y dará resultados según esos resultados, es decir, nombre, correo electrónico, etc.
Objeto de datos:
[ { name:lorem, email:lorem@example.com } ]Supongamos que hay dos campos de búsqueda, uno para el nombre y otro para el correo electrónico, y si el usuario escribe en ambos campos o en un campo, debería devolver una matriz con propiedades coincidentes.
ie searchInput ={ name:Lorem, email:lorem@example.com } result: [ { name:lorem, email:lorem@example.com } ]estoy almacenando los valores de entrada como este
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>He intentado varias respuestas aquí, pero hasta ahora no he obtenido los resultados que quiero.
He resuelto los problemas de búsqueda, pero ahora me enfrento a esto. ******** Otro problema ********
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); }por lo que la búsqueda funciona como se esperaba, pero ahora estoy perdiendo los datos originales y tengo que volver a cargar la página para obtener los datos originales. Entonces, ¿hay alguna forma de filtrar los datos sin perder los datos originales?
Solución:
const [searchInput, setSearchInput] = useState<any>(null); // change initial state to null // Fetch the data if searchInput is null useEffect(() => { if (!searchInput) { // Make the api call to fetch data } }, [searchInput]); // Changes in input handler const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => { const { name, value } = event.target; if (!!value) { setSearchInput({ ...searchInput, [name]: value }); } else { setSearchInput(null); // set null if there isn't any search input. } };La función de búsqueda sigue siendo la misma.
Puedes probar uno de estos:
// Ignorar a continuación
Intenta usar el gancho useEffect
useEffect(() => { // I suppose loadData(searchInput["email"], searchInput["name"]) }, [searchInput])O sea más claro con los resultados que desea
...la búsqueda funciona como se esperaba, pero ahora estoy perdiendo los datos originales y tengo que volver a cargar la página para obtener los datos originales.
Está perdiendo fidelidad de estado porque lo está sobrescribiendo con el resultado de los valores filtrados.
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!! }Entonces, ¿hay alguna forma de filtrar los datos sin perder los datos originales?
Sí, no sobrescriba la fuente de la verdad en el estado. Utilice la matriz de estado de los users guardados y los valores de estado del filtro para derivar el resultado representado. En otras palabras, realice el filtrado en línea al representar la matriz de users en la interfaz de usuario.
Ejemplo:
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 ))