首页 > 解决方案 > React Checkbox:子节点的更改无法重新渲染父节点?

问题描述

我正在为我的项目制作复选框,遗憾的是我花了一天时间在上面,但仍然无法解决问题。它有控制所有子复选框和子复选框的母复选框。

我想要做的是,如果子节点中的所有复选框都被选中,则必须选中父节点的 allChecked 复选框。如果任何复选框未选中,则必须取消选中父节点的 allChecked 复选框。

一开始我还以为是道具的问题。我将 'allChecked' 的值从 'cards' 赋予 'card' 和 '他们是否只给出作为道具的值?(如 true 或 false)'。但是经过一些实验,可以发现它们共享相同的变量。

我无法理解为什么我的代码在完全选中子复选框时不会更改父节点的复选框。据我所知,当属性发生变化时反应重新渲染节点,但在改变后,母亲中的复选框不会改变。

Cards.js

const Cards = ({ cards }) => {
    const numberOfCards = cards.length;
    const [allChecked, setAllChecked] = useState(false);
    const [checkedList, setCheckedList] = useState(new Set());

    const handleAllChecked = () => {
        setAllChecked(!allChecked);
    }

    return (
        <>
            <>
                <>
                    <input type="checkbox" value={allChecked} onChange={handleAllChecked} />
                </>
                <>
                    { cards.map(el => <Card
                                    id={el.id}
                                    key={el.id}
                                    checkedList={checkedList}
                                    setCheckedList={setCheckedList}
                                    allChecked={allChecked}
                                    setAllChecked={setAllChecked}
                                    numberOfCards={numberOfCards}
                                />) }
                </>
            </>
        </>
    )
}

Card.js

const Card = ({ id, checkedList, setCheckedList, allChecked, setAllChecked, numberOfCards }) => {
    const [checked, setChecked] = useState(false);

    const controlCheckedList = () => {
        if (!checked) {
            checkedList.add(id);
            setCheckedList(checkedList);
        } else {
            checkedList.delete(id);
            setCheckedList(checkedList);
        }
    }

    const handleChecked = () => {
        setChecked(!checked);
        controlCheckedList();
    }

    useEffect(() => {
        if (allChecked) {
            setChecked(true);
            checkedList.add(id);
            setCheckedList(checkedList);
        }
        else if (!allChecked&&checkedList.size===numberOfCards) {
            setChecked(false);
            setCheckedList(new Set());
        };
    }, [allChecked]);

    useEffect(()=>{
        if (checked) {
            if (checkedList.size===numberOfCards){ // here is the part where I think mother's allChecked has to be changed
                setAllChecked(true);
            }
        } else {
            if (checkedList.size<numberOfCards){ // here is the part where I think mother's allChecked has to be changed
                setAllChecked(false);
            }
        }
    }, [checked]);

    return (
        <>
            <input type="checkbox" checked={checked} onChange={handleChecked} />
        </>
    )
}

我觉得有一些简单的方法可以用 ContextAPI 或其他东西来解决它,但我真的想用 useState 和 useEffect 来解决它(我可以找到很多其他的例子)。我想知道的是为什么当所有复选框都被选中时,即使母复选框的值发生了变化,它也不会在母复选框上做出可见的更改?先感谢您。

标签: javascriptreactjsfrontend

解决方案


您不应该checkedvalueCards.js 中使用

<input type="checkbox" checked={allChecked} onChange={handleAllChecked} />

推荐阅读