Tengo un pequeño proyecto de reacción que contiene un formulario, estoy tratando de obtener múltiples valores de una casilla de verificación, pero cada vez que hago clic en un elemento (casilla de verificación) por primera vez, comienza como nulo, luego cuando hago clic en otro elemento, Almacena el primer artículo. Me gustaría almacenar varios elementos de una casilla de verificación. Aquí está el código a continuación.
import { useState } from "react"; const Toppings = () => { const [toppings, setToppings] = useState(null) const [toppingsArray, setToppingsArray] = useState([]) function handleCheck(event) { if (event.target.checked) { setToppings({ "type": event.target.id, "price": event.target.value }) console.log("toppings: ", toppings) toppingsArray.push(toppings) setToppingsArray([toppings]) console.log("toppings array: ", toppingsArray) } } return ( <> <h2>you can select multiple</h2> <form> <label htmlFor="pepperoni"> <input onChange={handleCheck} type="checkbox" name="pepperoni" id="pepperoni" value={300} /> pepperoni </label> <label htmlFor="cheese"> <input onChange={handleCheck} type="checkbox" name="cheese" id="cheese" value={200} /> cheese </label> <label htmlFor="onions"> <input onChange={handleCheck} type="checkbox" name="onions" id="onions" value={100} /> onions </label> </form> <p>you have selected {JSON.stringify(toppings)}</p> <p>you have {JSON.stringify(toppingsArray)}</p> </> ) } export default Toppings[enter image description here][1];Deshazte de la línea que dice toppingsArray.push(toppings) ya que toppingsArray está en estado, por lo que es inmutable
Agregue una línea que cambie la línea setToppingsArray a
setToppingsArray(toppingsArray=>[...toppingsArray, toppings])El enlace useState se puede usar como una función cuyo primer parámetro proporciona el estado inicial. Luego simplemente tomamos ese estado y lo extendemos en una matriz y agregamos lo nuevo
Tampoco hay razón para almacenar los ingredientes iniciales en el estado ya que no tiene interacción con el dom. Puede ser una const js
También debe tener un atributo marcado en las casillas de verificación que verifique si un complemento es la matriz de ingredientes.
Utilice este código.
function handleCheck(event) { const item = { "type": event.target.id, "price": event.target.value }; if (event.target.checked) { setToppings(item); if(toppingsArray.map(val => val["type"]).indexOf(item["type"]) == -1) setToppingsArray([...toppingsArray, item]); } else { setToppingsArray(toppingsArray.filter(val => val["type"] != item["type"])); } }Hay varias cosas que no están bien en su código.
console.log("toppings: ", toppings) justo después de setState le mostrará el estado obsoleto.setToppingsArray([toppings]) , que también es incorrecto porque ha enviado los datos a toppingsArray, por lo que necesita actualizar el estado pasando esa matriz, como este setToppingsArray(toppingsArray) .Para resolver todos estos problemas, podría hacer algo como esto dentro de su función handleCheck :
function handleCheck(event) { const newToppings = { type: event.target.id, price: event.target.value, }; if (event.target.checked) { setToppings(newToppings); toppingsArray.findIndex(top => top.type === newToppings.type) < 0 && setToppingsArray([...toppingsArray, newToppings]); } else { setToppingsArray(toppingsArray.filter(top => top.type !== newToppings.type)); } }