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

173
Views
actualizar la lista con useState más de una vez da como resultado una salida incorrecta

Tengo problemas para manejar una lista con useState en React. Tengo que agregar un elemento a la lista dos veces seguidas y solo se agrega el segundo elemento. El código:

Aplicación.js

 import React, { useState } from "react"; import ItemForm from "./itemForm"; function App() { const [itemList, setItemList] = useState([]); function addItem(item) { setItemList([...itemList, item]); } return ( <div> <ItemForm onAddItem={ addItem } /> { itemList && itemList.map((item, i) => <ul key={ i + itemList } >{ item }</ul>) } </div> ); } export default App;

ItemForm.js

 import React, { useState } from 'react'; function ItemForm({ onAddItem }) { const [inputValue, setInputValue] = useState(''); function handleSubmit(e) { e.preventDefault(); var item = e.target.item.value; // Here, I have to call onAddItem twice. onAddItem(item); onAddItem(item + " second time"); } return ( <div> <form onSubmit={ handleSubmit } > <input value={ inputValue } onChange={(e) => setInputValue(e.target.value) } name="item"></input> <button type="submit">Add</button> </form> </div> ) } export default ItemForm;

Este es el comportamiento real de la aplicación:

comportamiento real

Y este es el comportamiento esperado :

comportamiento esperado

¿Por qué sucede esto y cómo puedo solucionarlo?

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

0

Las actualizaciones de estado son asíncronas

Para sus dos llamadas, la matriz itemsList es exactamente la misma. :

Suponga que tiene una matriz: [1,2,3] . Lo que esencialmente hace su código es hacerlo [1,2,3,4] por primera vez y [1,2,3,5] por segunda vez.

 setItemList([...itemList, item]) //[1,2,3,4] setItemList([...itemList, item]) //[1,2,3,5]

Su matriz en la segunda actualización todavía usa el valor original.

Una forma de hacer esto puede usar este patrón que usa el estado anterior. Esta es una forma confiable de usar el estado anterior.

 import React, { useState } from "react"; import ItemForm from "./itemForm"; function App() { const [itemList, setItemList] = useState([]); function addItem(item) { setItemList(itemList => ([...itemList, item])); } return ( <div> <ItemForm onAddItem={ addItem } /> { itemList && itemList.map((item, i) => <ul key={ i + itemList } >{ item }</ul>) } </div> ); } export default App;
 import React, { useState } from 'react'; function ItemForm({ onAddItem }) { const [inputValue, setInputValue] = useState(''); function handleSubmit(e) { e.preventDefault(); var item = e.target.item.value; // Here, I have to call onAddItem twice. onAddItem(item); onAddItem(item + " second time"); } return ( <div> <form onSubmit={ handleSubmit } > <input value={ inputValue } onChange={(e) => setInputValue(e.target.value) } name="item"></input> <button type="submit">Add</button> </form> </div> ) } export default ItemForm;
about 4 years ago · Juan Pablo Isaza Report

0

La función pasada al componente ItemForm como accesorio, es decir, onAddItem , tiene un cierre sobre el valor de itemList que estaba en vigor cuando se creó esa función.

Como resultado, llamar a esa función dos veces con un valor diferente para item crea una nueva matriz con el mismo valor de itemList que cerró la función addItem .

Ejemplo:

Si la función addItem pasa al componente ItemForm tiene un cierre sobre el valor inicial de itemList , es decir, una matriz vacía; entonces la siguiente llamada a la función de establecimiento de estado:

 setItemList([...itemList, item]);

extiende la matriz vacía y luego agrega el nuevo item como se muestra a continuación.

 setItemList([...[], item]);

Llamar a la función addItem dos veces es lo mismo que:

 setItemList([...[], item]); setItemList([...[], item]);

También tenga en cuenta que el estado es constante dentro de una representación particular de un componente. El componente no puede ver el estado actualizado hasta que se vuelve a renderizar.

Solución

Puede pasar una función a setItemList para actualizar el estado en función del valor anterior de itemList :

 function addItem(item) { setItemList(currentState => [...currentState, item]); }

La opción alternativa es pasar una matriz a la función onAddItem :

 onAddItem([item1, item2]);

y cambie la función addItem como:

 function addItem(itemsArr) { setItemList([...itemList, ...itemsArr]); }
about 4 years ago · Juan Pablo Isaza Report

0

React no actualiza el estado inmediatamente después de llamar a setState , toma todas las llamadas a setState y las ejecuta antes de volver a procesarlas.

Entonces, en su caso, el segundo onAddItem está anulando el primero.

Para resolver tales problemas, debe cambiar algo de lógica en su código, por ejemplo:

 function addItem(...newItems) { setItemList(previousItemList => ([...previousItemList, ...newItems])); }

Ahora puede pasar varios elementos para agregar un elemento y llamarlo solo una vez.

 onAddItem(item, item + " second time");
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!