Estoy explorando la función reaccionar al onChange . La funcionalidad que me gustaría hacer es cuando se selecciona la casilla de verificación, me gustaría actualizar los datos locales para agregar algún valor cuando la casilla de verificación no está seleccionada, me gustaría simplemente completar los datos originales, el código que tengo parece hacer lo contrario de lo que quiero . cualquiera puede proporcionar alguna pauta?
import "./styles.css"; import { useState } from "react"; export default function App() { const localData = [{ name: "apple", phone: 12345 }]; const [check, setCheck] = useState(false); const [data, setData] = useState(localData); const handleOnChange = () => { setCheck(!check); check ? setData([...data, { name: "amazon", phone: 222 }]) : setData(data); }; return ( <div className="App"> <h1>Hello CodeSandbox</h1> <p> <input type="checkbox" check onChange={handleOnChange}></input> </p> <p>{JSON.stringify(data)}</p> </div> ); }setCheck se ejecuta de forma asíncrona. Entonces, en la función handleOnChange , justo después de setCheck(!check) , el valor de check aún no se ha establecido en el nuevo valor.
Podría usar un efecto aquí ya que desea el efecto secundario de cambiar data de cambiar el check . De esta manera, cada vez que se cambia el check , el efecto se dispara:
const handleOnChange = () => { setCheck(!check); }; useEffect(() => { check && setData((previous) => [...previous, { name: "amazon", phone: 222 }]); }, [check]);Sandbox actualizado: https://codesandbox.io/s/quirky-rain-hmhkk
No hay necesidad de usar dos estados, esa solución le dará más problemas cuando quiera agregar más opciones.
Yo optaría por un enfoque similar a este:
import "./styles.css"; import { useState } from "react"; const localData = [{ name: "apple", phone: 12345 }]; const extraData = [{ name: "amazon", phone: 222 }]; export default function App() { const [data, setData] = useState(localData); const handleOnChange = (item) => { if (!data.find(({ name }) => name === item.name)) setData([...data, item]); else setData(data.filter(({ name }) => name !== item.name)); }; return ( <div className="App"> <h1>Hello CodeSandbox</h1> <p> {extraData.map((item) => { return ( <input key={item.name} type="checkbox" checked={data.includes(({ name }) => name === item.name)} onChange={() => handleOnChange(item)} /> ); })} </p> <p>{JSON.stringify(data)}</p> </div> ); }Esto le permitirá agregar más casillas de verificación en el futuro.
Entonces, ¿quiere que los datos se agreguen a data cuando la casilla de verificación ESTÁ marcada? Simplemente invierta la condición del ternario que usa en handleOnChange :
import "./styles.css"; import { useState } from "react"; export default function App() { const localData = [{ name: "apple", phone: 12345 }]; const [check, setCheck] = useState(false); const [data, setData] = useState(localData); const handleOnChange = () => { setCheck(!check); !check ? setData([...data, { name: "amazon", phone: 222 }]) : setData(data); }; return ( <div className="App"> <h1>Hello CodeSandbox</h1> <p> <input type="checkbox" check onChange={handleOnChange}></input> </p> <p>{JSON.stringify(data)}</p> </div> ); }