Tengo el siguiente problema extraño, usando React. Estoy creando una aplicación de seguimiento de presupuesto, que tiene un presupuesto total, un formulario para agregar un nuevo gasto y al final muestra el gasto con el costo a continuación. El nuevo costo también se resta del presupuesto total. tengo los siguientes estados:
const [total, setTotal] = useState(1500); const [expense, setExpense] = useState({ name: "Expense", cost: "0" }); const [allExpenses, setAllExpenses] = useState([]);El primero es el presupuesto total. El segundo estado: gasto es el nuevo gasto, que se agrega desde el formulario. allExpenses es una matriz de objetos, que debe imprimirse debajo del formulario.
Estos son mis métodos de establecimiento, que ocurren onChange (en los campos de entrada) y onSubmit (enviando el formulario):
const handleSubmit = event =>{ event.preventDefault(); let exp = expense.name; let cost = expense.cost; alert( "New expense " + exp + " costs " + cost ); setTotal((prevTotal) => prevTotal - cost); const newAll = (prevAll) => ([...prevAll, expense]); setAllExpenses(newAll); } const handleChange = event =>{ setExpense((prevExpense) => ({ ...prevExpense, [event.target.name]: event.target.value })) }Y en la función de representación, debajo del formulario, llamo a la función array map() para imprimir encabezados con el nombre y el costo del gasto.
{allExpenses.map(({item, cost}) => {return <h1>{item} costs {cost}$</h1>})}También agregué un componente de visualización para rastrear si el estado cambia.
export function Printer (props){ return( <h1>{props.name} costs {props.cost}$</h1> /* Added as a change tracker. State DOES change. Issue is probably within the allExpenses state. */ ); }El problema es que el estado sí cambia. Si agrego un nuevo gasto, por ejemplo NewExpense, 12$, el componente de la impresora mostrará "NewExpense cuesta 12$". Sin embargo, la función de mapeo de la matriz mostrará " cuesta 12 $". El estado ha cambiado, pero el atributo expensas.nombre del objeto no se muestra después de la asignación. Todo lo demás parece estar funcionando bien. Intenté reescribir la llamada map() y el establecedor de estado setAllExpenses. Nada parece solucionar el problema, que es bastante peculiar. El formulario también está dentro del renderizado (no en un componente separado), por lo que no estoy pasando ningún estado a través de accesorios. ¿Que me estoy perdiendo aqui?
Debe realizar cambios en la función de mapa de matriz como se muestra a continuación.
{allExpenses.map(({name, cost}) => {return <h1>{name} costs {cost}$</h1>})}Esto debería imprimir "NewExpense cuesta 12 $".
Debe cambiar el estado allExpenses correctamente.
En lugar de esto
const newAll = (prevAll) => ([...prevAll, expense]); setAllExpenses(newAll);Prueba esto
setAllExpenses((prevAll) => [...prevAll, expense]);