ReactJs-Checkall上的复选框问题

时间:2019-02-22 05:23:42

标签: javascript reactjs checkbox

点击全部选中复选框时,我在react.js中遇到此错误,我将取消选择带有“ lot_no”和吊杆的项目,单击的项目消失了。

我有2种状态: checked data 其中 checked 包含该人员检查的所有项目,而 data 是所显示的所有项目。

我正在将选中状态与我的数据进行比较,如果选中状态包括来自 data 状态的项目,则该复选框应为已选中,否则未选中

请同时检查我的代码和演示。

https://stackblitz.com/edit/react-4v7wb6 enter image description here

我的示例数据是这样的:

const data = [
  {
    document_id: 10095,
    detail_info: []
  },
  {
    document_id: 12221,
    detail_info: []
  },
  {
    document_id: 12226,
    detail_info: [
      {
        id: 738,
        lot_no: "B12345"
      },
      {
        id: 739,
        lot_no: "C12345"
      }
    ]
  },
  {
    document_id: 12229,
    detail_info: [
      {
        id: 740,
        lot_no: "D12345"
      },
      {
        id: 741,
        lot_no: "E12345"
      }
    ]
  }
];
export default data;

代码:

class App extends Component {
  constructor() {
    super();
    this.state = {
      checked:[],
      data: data
    };
  }

  checkBoxClick(item, index, e) {
    let checked = this.state.checked;
    const getIndex = this.state.checked
      .map(e => {
        return e.document_id;
      }).indexOf(item.document_id)

    let index1 = index[0];
    let index2 = index[1];
    if (e.target.checked) {
      if (getIndex === -1) {
        if (index2 === null) {
          checked.push({
            document_id: item.document_id,
            detail_info: []
          });
        } else {
          checked.push({
            document_id: item.document_id,
            detail_info: [item.detail_info[index2]]
          });
        }
        this.setState({ checked: checked });
      } else {
        checked[getIndex].detail_info.push(item.detail_info[index2]);
        this.setState({ checked: checked });
      }
    }

    // uncheck
    else {
      let clickedIndex = checked[getIndex].detail_info.indexOf(
        item.detail_info[index2]
      );

      if (getIndex !== -1) {
        if (index2 === null) {
          checked.splice(getIndex, 1);

        } else {

          // if no more child is checked, remove the parent from checked state
          if (checked[getIndex].detail_info.length===1){
            checked.splice(getIndex, 1);

          } else{

          checked[getIndex].detail_info.splice(clickedIndex, 1);

          }

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

      }

    }
  }
  checkAll(e) {
     let {checked} = this.state
        if (e.target.checked){
            this.state.data.map((item,idx)=>{
                if (item.detail_info.length !==0 ){
                    checked.push({'document_id': item.document_id,
                    'detail_info': item.detail_info
                    })
                } else {
                    checked.push({'document_id': item.document_id,
                    'detail_info': [],
                    })
                }
                this.setState({checked:checked})

            })

        }
        else {
            this.state.data.map((item,idx)=>{
                    this.setState({checked:[]})

            })
        }
  }

  render() {
    return (
      <table>
        <thead>
          <tr>
            <th style={{ width: "20px" }}>
              <input type="checkbox" onChange={this.checkAll.bind(this)} /> All
            </th>
            <th>ID. </th>
            <th>Lot No.</th>
          </tr>
        </thead>
        {this.state.data.map((item, idx) => {
          const checkIfExist = obj => obj.document_id === item.document_id;
          let isChecked = this.state.checked.some(checkIfExist);
          return (
            <tbody key={idx}>
              {item.detail_info.length === 0 ? (
                <tr>
                  <td>
                    <input
                    checked={isChecked}
                      type="checkbox"
                      onChange={this.checkBoxClick.bind(this, item, [
                        idx,
                        null
                      ])}
                    />
                  </td>
                  <td>{item.document_id}</td>
                </tr>
              ) : (
                item.detail_info.map((a, b) => {
                  let isCheckedLot = false;
                  this.state.checked.map((c, d) => {
                    if (c.detail_info.length !== 0) {
                      return c.detail_info.map((e, f) => {
                        if (e.id === a.id) {
                          return (isCheckedLot = true);
                        }
                      });
                    }
                  });
                  return (
                    <tr key={b}>
                      <td>
                        <input
                          checked={isCheckedLot}
                          type="checkbox"
                          onChange={this.checkBoxClick.bind(this, item, [
                            idx,
                            b
                          ])}
                        />
                      </td>
                      <td>{item.document_id}</td>
                      <td>{a.lot_no}</td>
                    </tr>
                  );
                })
              )}
            </tbody>
          );
        })}
      </table>
    );
  }
}

1 个答案:

答案 0 :(得分:0)

问题是您在检查全部时是否将对detail_info的引用添加到检查列表中。在这段代码中('detail_info': item.detail_info

checkAll(e) {
     let {checked} = this.state
        if (e.target.checked){
            this.state.data.map((item,idx)=>{
                if (item.detail_info.length !==0 ){
                    checked.push({'document_id': item.document_id,
                    'detail_info': item.detail_info
...

当您删除项目时,它还将从数组中删除详细信息,从而也将其从state.data中删除。解决方法是在将副本放入checked数组之前复制副本。参见下文('detail_info': item.detail_info.slice()

checkAll(e) {
     let {checked} = this.state
        if (e.target.checked){
            this.state.data.map((item,idx)=>{
                if (item.detail_info.length !==0 ){
                    checked.push({'document_id': item.document_id,
                    'detail_info': item.detail_info.slice()
...