使用钩子选择和取消删除所有复选框



我有一些复选框的数组状态,我在其中捕获那些为true(已选中(的标签。必须忽略错误。

感谢你们在另一个线程中的一些人,我能够生成一个复选框列表。但我用全选开关碰到了另一面墙。

const handleSwitch = (e) => {
if(e.target.checked) {
setActive(true);
const updatedCheckedState = checkedState.map(element => element.checked = true);
setCheckedState([...updatedCheckedState]);   
} else {      
setActive(false)
const updatedCheckedState = checkedState.map(element => element.checked = false);
setCheckedState([...updatedCheckedState]);   
}
}

特别是上面的这个功能。同样,如果我手动选中里面的所有复选框,它需要知道所有复选框都已选中,并使活动状态为true。如果我至少能在第一部分得到帮助,我相信我能自己解决另一部分。

如果你想乱搞的话,这里有一个沙盒。谢谢

您的沙箱已完全损坏。您跟踪检查状态的方式在内部不一致。(

罪魁祸首(在Filter.js中(是:

  • 在第119行,您将checkedState视为字典,但在handleSwitchhandleOnChange中,您将其视为数组(但据我所知,数组方法中的逻辑仍然不起作用。
    • 如果你想让它是一个数组,就让它是值为"的字符串;checkedLabels";数组,并将复选框组件上的checked设置为checkedLabels.includes(item.label)
    • 如果你想让它成为一本字典:
      • handleOnChange需要简单地切换当前单击的元素,就像[e.target.name]: !checkedState[e.target.name]一样
      • handleSwitch需要为data中的每个元素添加一个条目,视情况设置为truefalse

示例(codesandbox(:

const handleSwitch = (e) => {
if (e.target.checked) {
setActive(true);
setCheckedState(
Object.fromEntries(data.map((item) => [item.label.toLowerCase(), true]))
);
} else {
setActive(false);
setCheckedState({});
}
};
const handleOnChange = (e) => {
setCheckedState({
...checkedState,
[e.target.name]: !checkedState[e.target.name]
});
};
<CustomCheckbox
size="small"
name={item.label.toLowerCase()}
checked={checkedState[item.label.toLowerCase()] ?? false}
onChange={handleOnChange}
/>

从OP编辑我调整了hnadleChange函数为

const handleOnChange = (e) => {
if (e.target.checked) {
setCheckedState({
...checkedState,
[e.target.name]: !checkedState[e.target.name]
});
} else {
const updatedCheckedState = {...checkedState};
delete updatedCheckedState[e.target.name];
setCheckedState(updatedCheckedState);   
}
};

以前,当您取消选中以前选中的复选框时,它允许添加假值。这将删除


编辑:要对数组执行此操作,您需要在检查时添加到数组中,在取消检查时从中删除。然后执行includes,查看是否应选中单个复选框。

此外,您可以在handleOnChange中执行一个简单的setActive(newCheckedItemLabels.length === data.length);来实现您的其他需求。

这个代码沙盒使用数组而不是对象来完成所需的一切。

值得注意的是:

const [checkedItemLabels, setCheckedItemLabels] = useState([]);
const handleSwitch = (e) => {
if (e.target.checked) {
setActive(true);
setCheckedItemLabels(data.map((item) => item.label.toLowerCase()));
} else {
setActive(false);
setCheckedItemLabels([]);
}
};
const handleOnChange = (e) => {
const newCheckedItemLabels = checkedItemLabels.includes(e.target.name)
? checkedItemLabels.filter((label) => label !== e.target.name)
: [...checkedItemLabels, e.target.name];
setCheckedItemLabels(newCheckedItemLabels);
setActive(newCheckedItemLabels.length === data.length);
};
<CustomCheckbox
size="small"
name={item.label.toLowerCase()}
checked={checkedItemLabels.includes(
item.label.toLowerCase()
)}
onChange={handleOnChange}
/>

添加到@JohnPaulR答案。您可以添加useEffect摄影以达到您的附加要求。

如果我手动选中里面的所有复选框,它需要知道所有复选框都已选中,并使活动状态为true。

useEffect(() => {
const checkedTotal = Object.keys(checkedState).reduce((count, key) => {
if (checkedState[key]) {
return count + 1;
}
}, 0);
setActive(data.length === checkedTotal);
}, [checkedState]);

完整的工作示例https://codesandbox.io/s/still-water-btyoly

最新更新