我有一个working nested checkbox example我正在努力将其实现到我的应用程序中。复选框的逻辑功能足以涵盖这 7 种情况
- Scenario - No children, no parent selected
- Select the parent -> select the parent and all children
- Select a child -> select that child and its parent
- Scenario - All children and the parent selected
- Select the parent -> deselect the parent and all children
- Select a child -> deselect only that child
- Scenario - Some children and the parent selected
- Select the parent -> select all unselected children
- Select a child -> select that child, parent remains selected
- Deselect last child -> deselect the child and deselect the parent
我遇到的问题是,在选择或取消选择子项的情况下,父复选框的状态会更新,但复选框的实际视觉变化并未发生。
来 self 的代码:
<Checkbox
disableRipple
edge="start"
checked={sub.checked}
onChange={() =>
this.handleCheckClick(sub.id, parentIndex)
}
/>
Material-UI <Checkbox />
组件位于项目列表内部,每个项目都有一个后续的项目列表,这些项目有自己的 <Checkbox />
分别组成。当我选择列表的父复选框时,状态会通过 handleCheckClick()
正确更改。方法,并且状态被正确更新,并且视觉更新如您所想的那样发生。
当单击子级时,理想的情况是选择父级,它处于 react 组件的状态,但尽管复选框的 checked
但视觉方面的变化并未发生。状态被映射到状态。
有趣的是,如果我使用这样的 native 输入:
<input
type="checkbox"
disableRipple
edge="start"
checked={sub.checked}
onChange={() =>
this.handleCheckClick(sub.id, parentIndex)
}
/>
正确的行为既可以在视觉上显示,也可以在状态中显示(就像已经那样)。我不确定这是否是特定于 Material-UI 的错误,或者竞争条件,或者其他发生的事情,但我确实知道 handleCheckClick()
中的逻辑功能健全,因为更改在 react 状态下正确显示。
最佳答案
您实际上有一个警告,表明发生了什么:
Warning: A component is changing an uncontrolled input of type checkbox to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/docs/forms.html#controlled-components
问题是您没有在 createSubscriptions
中初始化 checked
状态(请参阅下面的代码),因此最初 sub.checked
为 未定义
。这会导致 Material-UI 将复选框视为 uncontrolled ,因此稍后指定 checked
状态无效。
function createSubscriptions() {
const statusSet = ["Processing", "Completed", "Submitted", "Error"];
const quantity = (faker.random.number() % 10) + 1;
const subscriptions = [];
let x = 0;
while (x < quantity) {
subscriptions.push({
id: faker.random.uuid(),
name: faker.lorem.words(),
description: faker.lorem.sentence(),
created: faker.date.past(),
status: statusSet[faker.random.number() % 4],
checked: false, // ADDING THIS FIXES IT
geoJson: {
features: createGeoJson()
}
});
x += 1;
}
return subscriptions;
}
或者,您可以在渲染复选框时处理此问题:
<Checkbox
disableRipple
edge="start"
checked={sub.checked || false}
onChange={() =>
this.handleCheckClick(sub.id, parentIndex)
}
/>
关于javascript - Material-UI 嵌套复选框选择不会在 DOM 中呈现对父级的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58013677/