select 一组所有复选框的逻辑不正确

Incorrect Logic to select a set of all checkboxes

考虑以下代码,有多个复选框,其字段为:

<Checkbox
         checked={checked[element]}
         onChange={(e) => {
                            setChecked({ ...checked, [e.target.name]: !checked[e.target.name] });
                           }}
         name={element}
 />

现在考虑一个用于选中所有复选框的按钮:

<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>

onCLick 逻辑通过所有元素的数组呈现,并且应该将它们的值设置为 true,但由于某种原因它只将最后一个复选框的值设置为 true 。这是供您参考的 checked 状态变量:

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
    });

问题是你的循环

Object.keys(checked).forEach((e) => {
   setChecked({ ...checked, [e]: !checked[e] });
});

setChecked 是一个异步调用。也就是说,您的检查状态在下一次渲染之前不会改变。当您将一个状态的值设置为 true 时,下一次调用会将其设置回 false,并将其当前键值设置为 true。它会重复,直到你到达最后一个元素。因此,为什么只有最后一个复选框是 true.

例如,考虑这个状态

const [checked, setChecked] = useState({a : false, b: false})

现在考虑这个。

setChecked({ ...checked, a: true})
console.log(checked) // returns { a: false, b: false}
setChecked({ ...checked, b: true})

由于 ...checked,第二个 setChecked 调用覆盖了第一个调用,并且由于检查状态由于异步性质而没有改变,因此检查只会将键 b 设置为true

您应该复制 checked 而不是您的代码。

const checkedCopy = { ...checked }
Object.keys(checkedCopy).forEach((e) => {
   checkedCopy.e = !checkedCopy.e;
});
setChecked(checkedCopy)

有了这个,您现在只有 1 个 setChecked 通话。