简体   繁体   English

Material-UI 嵌套复选框选择不会将更改呈现给 DOM 中的父级

[英]Material-UI Nested Checkbox selection doesn't render change to parent in DOM

I have a working nested checkbox example I am working on implementing into my application.我有一个正在工作的嵌套复选框示例,我正在将其实现到我的应用程序中。 The logic for the checkboxs is functional enough to cover theses 7 cases复选框的逻辑功能足以涵盖这 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

The issue I am running into is that in scenarios when the child is selected or deselected, the parent checkbox's state is updated, but the actual visual change of the checkbox isn't happening.我遇到的问题是,在选择或取消选择子项的情况下,父复选框的 state 会更新,但复选框的实际视觉变化并未发生。

From my code:从我的代码:

<Checkbox
  disableRipple
  edge="start"
  checked={sub.checked}
  onChange={() =>
    this.handleCheckClick(sub.id, parentIndex)
  }
/>

The Material-UI <Checkbox /> component is inside of a list of items, and each item has a subsequent list of items with their own <Checkbox /> components respectively. Material-UI <Checkbox />组件位于项目列表中,每个项目都有一个后续项目列表,每个项目都有自己的<Checkbox />组件。 When I select the parent checkbox of the list the state changes properly through that handleCheckClick() method, and the state is updated properly, and the visual update happens as you would think.当我 select 列表的父复选框 state 通过该handleCheckClick()方法正确更改时,state 已正确更新,并且视觉更新发生为

When the child is clicked, an ideal situation would be that the parent is then selected, which it is in the react component's state, but the visual aspect of the change isn't taking place despite the checkbox's checked state being mapped to state.单击子级时,理想的情况是然后选择父级,它位于反应组件的 state 中,但是尽管复选框的checked state 被映射到 Z9ED36E2EA9942EF5786B,但视觉方面并没有发生变化。

The interesting part is that if I use a native input like this:有趣的是,如果我使用这样的本机输入:

<input
  type="checkbox"
  disableRipple
  edge="start"
  checked={sub.checked}
  onChange={() =>
    this.handleCheckClick(sub.id, parentIndex)
  }
/>

The correct behavior is both displayed visually, but also in state (like it already was).正确的行为既显示在视觉上,也显示在 state 中(就像它已经是一样)。 I am not sure if this is an error specific to Material-UI, or a race condition, or something else happening, but I do know that the logic in the handleCheckClick() function is sound as changes are being displayed properly in the react state.我不确定这是特定于 Material-UI 的错误,还是竞争条件,或发生了其他事情,但我知道handleCheckClick() function 中的逻辑是合理的,因为在反应 Z9ED39E2EA93158EF57B36A9 中正确显示了更改。

You actually have a warning indicating what is going on:您实际上有一个警告指示正在发生的事情:

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更多信息: https://reactjs.org/docs/forms.html#controlled-components

The issue is that you are not initializing the checked state in createSubscriptions (see code below), so initially sub.checked is undefined .问题是您没有在createSubscriptions中初始化checked的 state (请参见下面的代码),因此最初sub.checkedundefined This causes Material-UI to treat the checkbox as uncontrolled , so specifying the checked state later has no effect.这会导致 Material-UI 将复选框视为不受控制的,因此稍后指定checked的 state 无效。

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

编辑嵌套复选框材质 UI

Alternatively, you can handle this at the point of rendering the Checkbox:或者,您可以在呈现复选框时处理此问题:

<Checkbox
  disableRipple
  edge="start"
  checked={sub.checked || false}
  onChange={() =>
    this.handleCheckClick(sub.id, parentIndex)
  }
/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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