如何使用反应钩子限制多个复选框输入

时间:2021-04-20 00:06:50

标签: javascript reactjs

我正在尝试实现一个表单,其中用户只需选中 3 个标记三个框并取消选中标记。

无论出于何种原因,setCurrentData(currentData - 1) 都不会递减。因此,当用户取消选择时,当他们最多选择三个时,currentData 仍然设置为 3,并且将无法选中复选框。

减量不起作用的任何原因?似乎它应该工作没有?我是否遗漏了一些微不足道的东西?

这个概念类似于这个 stackoverflow 答案。 selection limit function not working on checkbox form reactjs

使用此代码沙箱

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

2 个答案:

答案 0 :(得分:0)

取消选择时删除数组中的项目所需的句柄更改。检查最后一个 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]
      );

答案 1 :(得分:-1)

代码中有错字 let uniqueItems = [...new Set(items) 缺少结束 ]

我认为你的代码没有问题,只是一个可能欺骗你的观察

console.log("before", currentData)
setCurrentData(currentData - 1)
console.log("after", currentData)

您不能依赖 currentData 之后的 setState,因为它是异步的,可能尚未更改。