Considere el siguiente código, hay varias casillas de verificación cuyos campos son:
<Checkbox checked={checked[element]} onChange={(e) => { setChecked({ ...checked, [e.target.name]: !checked[e.target.name] }); }} name={element} />Ahora considere un botón usado para marcar todas las casillas de verificación:
<Button variant="contained" onClick={() => { setIsAllChecked(!isAllChecked); Object.keys(checked).forEach((e) => { setChecked({ ...checked, [e]: !checked[e] }); }); }} marginRight={2} sx={{ margin: '2rem' }} > {isAllChecked ? 'Unselect All' : 'Select All'} </Button> la lógica onCLick representa a través de una matriz de todos los elementos, y se supone que debe establecer su valor en verdadero, pero por alguna razón solo establece el valor de la última casilla de verificación como verdadero . aquí está la variable de estado checked para su referencia:
const [checked, setChecked] = useState({ 'Add Employee Importer': false, 'Employee LOP': false, 'LOP Reversal Importer': false, 'Employee Bank Details': false, 'Employee Loan Details': false, 'Employee Category': false, 'Employee Resignation': false, 'Bulk Salary Information Of Employees': false, 'Basic Employee Information': false, 'Employee PF_ESI Details': false, 'Final Settlement Details': false, 'Add revised salary': false });El problema es tu bucle aquí
Object.keys(checked).forEach((e) => { setChecked({ ...checked, [e]: !checked[e] }); }); setChecked es una llamada asíncrona . Es decir, su estado marcado no cambiará hasta el próximo renderizado. Cuando establece el valor de un estado en true , la siguiente llamada lo restablecerá en false y su valor clave actual en verdadero. Lo repetirá hasta que esté en su último elemento. Por lo tanto, por qué solo la última casilla de verificación es true .
Por ejemplo, considere este estado
const [checked, setChecked] = useState({a : false, b: false})Ahora considera esto.
setChecked({ ...checked, a: true}) console.log(checked) // returns { a: false, b: false} setChecked({ ...checked, b: true}) La segunda llamada setChecked sobrescribe la primera llamada debido a ...checked , y dado que los estados marcados no han cambiado debido a la naturaleza asíncrona, marcado solo establecería la clave b en true
En lugar de su código, debe hacer una copia de checked para hacer esto.
const checkedCopy = { ...checked } Object.keys(checkedCopy).forEach((e) => { checkedCopy.e = !checkedCopy.e; }); setChecked(checkedCopy) Con esto, ahora solo tiene 1 llamada setChecked .