[英]How to limit multiple checkbox inputs using react hooks
I'm trying to implement a form where a user is only only to check 3 mark three boxes and uncheck mark.我正在尝试实现一个表单,用户只需选中 3 标记三个框并取消选中标记。
For whatever reason setCurrentData(currentData - 1)
doesn't decrement.无论出于何种原因
setCurrentData(currentData - 1)
都不会减少。 Therefore, when a user deselects, the currentData
is still set to 3 when they select up to three, and will not be able to check mark a box.因此,当用户取消选择时,
currentData
仍然设置为 3,当他们 select 最多三个时,将无法选中一个框。
Any reason why the decrement isn't working?减量不起作用的任何原因? Seems like it should work no?
似乎它应该工作不? Am I missing something trivial?
我错过了一些微不足道的事情吗?
The concept is similiar to this stackoverflow answer.这个概念类似于这个stackoverflow答案。 selection limit function not working on checkbox form reactjs
选择限制 function 不适用于复选框形式 reactjs
with this code sandbox使用此代码沙箱
https://codesandbox.io/s/j4yyx9v6l5?fontsize=14 https://codesandbox.io/s/j4yyx9v6l5?fontsize=14
const Survey = (props) => {
const { t } = useTranslation();
const [checkedItems, setCheckedItems] = useState([]);
const [currentData, setCurrentData] = useState(0);
const [comments, setComments] = useState("");
const handleChange = useCallback(
(e) => {
console.log("after", currentData)
let isSelected = e.currentTarget.checked;
const limit = 3
let item = e.target.name
let text = e.target.value
let items = [...checkedItems, item];
let uniqueItems = [...new Set(items)]
if (text) {
setComments(text)
}
if (isSelected) {
if (currentData < limit) {
setCurrentData(currentData + 1)
setCheckedItems(uniqueItems);
} else {
e.preventDefault();
setCurrentData(currentData - 1)
e.currentTarget.checked = false;
}
} else {
console.log("before", currentData)
setCurrentData(currentData - 1)
console.log("after", currentData)
}
}, [checkedItems, comments]
);
return (
<React.Fragment>
{
surveyItems.map((item, index) => {
return (
<Checkbox
key={index}
name={item.name}
label={item.value}
onChange={handleChange}
/>
)
})
}
<TextBox onChange={handleChange}/>
</React.Fragment>
)
};
The handle change needed to remove the items in the array when deselected.取消选择时删除数组中的项目所需的句柄更改。 Check the last else block.
检查最后一个 else 块。
const handleChange = useCallback(
(e) => {
const limit = 3
let isSelected = e.currentTarget.checked;
let item = e.target.name
let text = e.target.value
if (text) {
setComments(text)
}
if (isSelected) {
if (checkedItems.length < limit) {
setCheckedItems([item, ...checkedItems]);
} else {
e.preventDefault();
e.currentTarget.checked = false;
}
} else {
const findIndexOfItem = checkedItems.findIndex((element) => element === item)
checkedItems.splice(findIndexOfItem, 1)
setCheckedItems(checkedItems)
}
}, [checkedItems, comments]
);
There is a typo in the code let uniqueItems = [...new Set(items)
missing closing ]
代码中有错别字
let uniqueItems = [...new Set(items)
missing closing ]
I think there is no problem with your code, just an observation that may trick you我认为您的代码没有问题,只是可能会欺骗您的观察
console.log("before", currentData)
setCurrentData(currentData - 1)
console.log("after", currentData)
You can't rely in the currentData
after a setState
because it is async, probably isn't changed yet.您不能在
setState
之后依赖currentData
,因为它是异步的,可能尚未更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.