简体   繁体   English

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM