Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

92
Views
Almacene una copia del estado de los datos antes de aplicar y después de borrar el filtro

Tengo una aplicación simple que llama a una API, devuelve los datos (como una matriz de objetos), establece un estado de datos y completa algunos cuadros y gráficos.

 const loadData = async () => { const url = 'https://my-api/api/my-api'; const response = await fetch(url); const result = await response.json(); setData(result.data); }

Después de configurar los datos, el estado de los datos se envía a cada componente y todo se rellena. Creé un panel de filtros que puede filtrar los datos completos existentes (por ejemplo, un filtro de género que filtra los datos del género seleccionado). Lo que hice, y obviamente está mal, es crear un controlador onChange que filtra los datos al género seleccionado y luego usa setData (enviado como accesorio; también la variable de estado, data ) para establecer los datos filtrados. Cuando borro el filtro, los datos originales no filtrados se reemplazan por los datos filtrados, por lo que los datos originales se pierden.

 const genderFilterHanlder = (e) => { const filteredData = data.filter(x => x.gender === e.target.value); setData(filteredData); }

Intenté crear un estado intermedio que conserva los datos originales y luego, al borrar los filtros, establece los datos ( setData ) en el original. Pero esto se rompe cuando tengo un filtro que le permite elegir varios valores (como varios idiomas; puedo elegir un idioma, borrarlo con éxito, pero si elijo dos idiomas, luego borro uno, se rompe porque los datos ahora son los primeros datos de filtro elegidos).

¿Cómo haría esto?

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Dejaría data solos y tendría un miembro de estado filteredData separado que configuras usando un efecto:

 const [filteredData, setFilteredData] = useState(data); const [filter, setFilter] = useState(""); // ... useEffect(() => { const filteredData = filter ? data.filter(/*...apply filter...*/) : data; setFilteredData(filteredData); }, [filter, data]); // <=== Note our dependencies // ... // ...render `filteredData`, not `data`...

Luego, su controlador de cambios solo actualiza el filter ( setFilter(/*...the filter...*/) ).

De esa manera, cada vez que cambie el filtro, o cada vez que cambien los data , los datos se filtran y representan.

Ejemplo en vivo:

 const { useState, useEffect } = React; const Child = ({data}) => { const [filteredData, setFilteredData] = useState(data); const [filter, setFilter] = useState(""); useEffect(() => { if (!filter) { setFilteredData(data); return; } const lc = filter.toLocaleLowerCase(); const filteredData = filter ? data.filter(element => element.toLocaleLowerCase().includes(lc)) : data; setFilteredData(filteredData); }, [filter, data]); // <=== Note our dependencies return <div> <input type="text" value={filter} onChange={({currentTarget: {value}}) => setFilter(value)} /> <ul> {filteredData.map(element => <li key={element}>{element}</li>)} </ul> </div>; }; const greek = [ "alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta", "iota", "kappa", "lambda", "mu", "nu", "xi", "omicron", "pi", "rho", "sigma", "tau", "upsilon", "phi", "chi", "psi", "omega", ]; const initialData = greek.slice(0, 4); const Example = () => { const [data, setData] = useState(initialData); useEffect(() => { const handle = setInterval(() => { setData(data => { if (data.length < greek.length) { return [...data, greek[data.length]]; } clearInterval(handle); return data; }); }, 800); return () => { clearInterval(handle); }; }, []); return <Child data={data} />; }; ReactDOM.render(<Example />, document.getElementById("root"));
 <div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"></script>

about 4 years ago · Juan Pablo Isaza Report

0

Necesita tener dos estados en su caso. Puede seguir el siguiente ejemplo.

 const data = [ { id: 1, name: "Mahela" }, { id: 2, name: "Sangakkara" }, { id: 3, name: "Dilshan" }, { id: 4, name: "Malinga" }, { id: 5, name: "Rangana" }, { id: 6, name: "Kulasekara" } ]; const [inputValue, setInputValue] = useState(""); const [filtered, setFiltered] = useState([]); const inputChangeHandler = (e) => { setInputValue(e.target.value); setFiltered(data.filter((item) => item.name === e.target.value)); }; return ( <div className="App"> <input type="text" value={inputValue} onChange={inputChangeHandler} /> {filtered.length > 0 && filtered.map((item) => <p>{item.name}</p>)} {filtered.length === 0 && data.map((item) => <p>{item.name}</p>)} </div> );

Aquí he usado constante para la matriz de datos. Puede utilizar su estado de datos. No reemplace el estado de los datos con datos nuevos, en su lugar use el segundo estado para los datos filtrados.

about 4 years ago · Juan Pablo Isaza Report

0

no cambie su estado después de filtrar. mantenga sus datos originales y obtenga una copia de ellos en una variable y haga sus cosas en ellos como filtrar. luego use esa variable para representar los datos filtrados y si desea borrar la entrada o cualquier otra cosa, puede usar su estado original que ha estado almacenando.

 const FilterData = () => { const [data, setData] = useState([]); const [select, setSelect] = useState(); const loadData = async () => { const url = "https://my-api/api/my-api"; const response = await fetch(url); const result = await response.json(); setData(result.data); }; const filteredData = data.filter((item) => { if (!select) return null; return item.gender !== select; }); return ( <div> <select>...</select> {filteredData.map(...)} </div> ); };
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!