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
通话。
考虑以下代码,有多个复选框,其字段为:
<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
通话。