关闭模态后如何保存复选框选中状态?

时间:2019-07-26 20:30:12

标签: javascript reactjs material-ui

我有一个带有多个复选框的模态。就像模式滤波器...

因此,如果我选中了复选框,请关闭模态并再次打开它,必须单击选中的复选框。 (在这里,我真的不知道该怎么做:/)

如果我选中了该复选框并单击“清洁过滤器” button,则所有checbkoxes必须未选中。 (在这里,我有一个方法可以做到,但不起作用:/)

有人可以帮助我吗?我该怎么办?

我在codeandbox上上传了代码,以查看其工作方式:CodeSandbox here

我的结构:

<button onClick={this.toggleDrawer(true)}>OPEN MENU</button>
<SwipeableDrawer
  anchor="top"
  open={this.state.top}
  onClose={this.toggleDrawer(false)}
  onOpen={this.toggleDrawer(true)}
>
  <div style={{ padding: "15px" }}>
    {data.map(element => {
      return (
        <div key={element.Name}>
          <p>{element.Name}</p>
          {element.Cont.map(item => {
            return (
              <FormControlLabel
                key={item.id}
                control={
                  <Checkbox
                    onChange={e => this.onChangeBox(e, item.id)}
                    checked={this.state.checkboxArray[item.id]}
                    iditem={item.id}
                  />
                }
                label={item.contName}
              />
            );
          })}
        </div>
      );
    })}
  </div>

  <div style={{ display: "flex", padding: "15px" }}>
    <div onClick={this.toggleDrawer(false)}>
      <button
        style={{
          background: "red",
          color: "white",
          padding: "9px"
        }}
      >
        CLOSE
      </button>
    </div>

    <div onClick={this.unChecked}>
      <button
        style={{
          background: "blue",
          color: "white",
          padding: "9px"
        }}
      >
        CLEAN ITENS
      </button>
    </div>
  </div>
</SwipeableDrawer>

这是我打开/关闭模式的方法,选中复选框,然后取消选中它们:

  toggleDrawer = open => event => {
    console.log("clicou");
    if (
      event &&
      event.type === "keydown" &&
      (event.key === "Tab" || event.key === "Shift")
    ) {
      return;
    }
    this.setState({ top: open });
  };

  onChangeBox = (event, iditem) => {
    this.handleCheckbox(event.target.checked, iditem);
    let checkBoxCurrentState = this.state.checkboxArray;
    checkBoxCurrentState[iditem] = !checkBoxCurrentState[iditem];
    this.setState({
      checkboxArray: checkBoxCurrentState
    });
  };

  unChecked = () => {
    let resetArray = new Array(data.length).fill(false);
    this.setState({
      checkboxArray: resetArray
    });
  };

2 个答案:

答案 0 :(得分:0)

如果您想直接跳转到解决方案,请参阅工作沙箱:https://codesandbox.io/s/material-demo-rcs5p

下面,我将解释我所做的所有更新。

让我们尝试集中一些代码。除了直接映射位于沙箱顶部的data数组外,我们还可以将该数组存储在您的状态中。

class MenuCheckbox extends React.Component {
  state = {
    drawerOpen: false,
    data: data
  };
....

然后,我们将迭代状态数组以在您的抽屉中呈现复选框。这样做的原因是我们每次进行更改时都具有更新的本地参考数据:

  render() {
    return (
      <div>
        <button onClick={this.toggleDrawer(true)}>OPEN MENU</button>
        <SwipeableDrawer
          anchor="top"
          open={this.state.drawerOpen}
          onClose={this.toggleDrawer(false)}
        >

太好了,现在让我们看一下数据数组。为了使事情变得容易,我们应该为每个项目赋予checked属性。这将有助于跟踪切换模态时应检查/不检查的项目。这样更干净,更明确。

对数据数组中的所有项目重复的示例:

  {
    Name: "Item 1",
    Cont: [
      {
        id: 1,
        contName: "Name 1",
        checked: false
      },
      {
        id: 2,
        contName: "Name 2",
        checked: false
      },
      {
        id: 3,
        contName: "Name 3",
        checked: false
      }
    ]
  }

现在很酷,我们的数据结构已经很好地设置了。我们可以编写一些简洁的逻辑来更新复选框。查看数组,我们有一组项目{}(级别1),其中每个项目都有自己的内部数组[](称为Cont(级别2),该数组存储我们的复选框状态

因此,自然地,要创建一个可以针对右侧复选框的函数,我们至少需要2个参数,即一组外部项目的索引和内部Cont项目的索引。点击复选框后,我们将触发此操作:

  onChangeBox = (dataIndex, contIndex) => {
    //turns our array into a string, then parses it back to an array. This is the best way to do a deep clone
    const data = JSON.parse(JSON.stringify(this.state.data));

    data[dataIndex].Cont[contIndex].checked = !data[dataIndex].Cont[contIndex]
      .checked;

    this.setState({
      data: data
    });
  };

在函数中,首先我们克隆数组以避免任何间接的状态突变。然后使用该新数组,找到选中的复选框,并简单地将checked属性设置为与当前属性相反的属性。最后,我们使用该新数据更新状态数组。

这将适用于检查和取消检查。

在这些复选框的呈现逻辑中,我们可以使用.map()的第二个参数来传入相应项目的索引。我们可以通过每个续项的内部.map()传递外部索引,而通过内部.map()传递内部索引。

  render() {
    return (
      <div>
        <button onClick={this.toggleDrawer(true)}>OPEN MENU</button>
        <SwipeableDrawer
          anchor="top"
          open={this.state.drawerOpen}
          onClose={this.toggleDrawer(false)}
        >
          <div style={{ padding: "15px" }}>
            {this.state.data.map((item, elementIndex) => {
              return (
                <div key={item.Name}>
                  <p>{item.Name}</p>
                  {item.Cont.map((contItem, contIndex) => {
                    return (
                      <FormControlLabel
                        key={contItem.id}
                        control={
                          <Checkbox
                            onChange={() =>
                              this.onChangeBox(elementIndex, contIndex)
                            }
                            checked={contItem.checked}
                            iditem={contItem.id}
                          />
                        }
                        label={contItem.contName}
                      />
                    );
                  })}
                </div>
              );
            })}
          </div>

最后要清除复选框,我们只需要一个函数即可创建全新的项目/复选框数组,其中所有contItem的检查值都设置为false。因此,我们将使用.map()和嵌套的.map()

  unChecked = () => {
    const { data } = this.state;
    const updatedData = data.map(item => {
      return {
        ...item,
        Cont: item.Cont.map(contItem => {
          return {
            ...contItem,
            checked: false
          };
        })
      };
    });

    this.setState({ data: updatedData });
  };

几乎全部。希望这对您有所帮助!

答案 1 :(得分:0)

请注意您的数据更改。

这应该让您入门。

https://codesandbox.io/embed/material-demo-4z6os