在 ReactJS 中,我如何跟踪一组复选框的状态?

In ReactJS how do I keep track of the state of a group of checkboxes?

我正在尝试跟踪在我所在的州选中了哪些复选框(您可以选中多个复选框)。我希望能够选中和取消选中这些框,并跟踪选中的框的 ID。稍后我会用这些值做一些事情。这是我目前所拥有的:

    import React, { Component } from 'react'
    import './App.css'
    import  CheckBox  from './CheckBox'


    class App extends Component {
      constructor(props) {
        super(props)
        this.state = {
          fruits: [
            {id: 1, value: "banana", isChecked: false},
            {id: 2, value: "apple", isChecked: false},
            {id: 3, value: "mango", isChecked: false},
            {id: 4, value: "grape", isChecked: false}
          ],
          fruitIds: []
        }
      }

      handleCheckChildElement = (e) => {
        const index = this.state.fruits.findIndex((fruit) => fruit.value === e.target.value),
          fruits = [...this.state.fruits],
          checkedOrNot = e.target.checked === true ? true : false;
          fruits[index] = {id: fruits[index].id, value: fruits[index].value, isChecked: checkedOrNot};
          this.setState({fruits});
          this.updateCheckedIds(e);
        }

      updateCheckedIds = (e) => {
        const fruitIds = [...this.state.fruitIds],
            updatedFruitIds= fruitIds.concat(e.target.id);
          this.setState({updatedFruitIds});
      }

      render() {
        const { fruits } = this.state;
        if (!fruits) return;

        const fruitOptions = fruits.map((fruit, index) => {
          return (
            <CheckBox key={index}
              handleCheckChildElement={this.handleCheckChildElement}
              isChecked={fruit.isChecked}
              id={fruit.id}
              value={fruit.value}
            />
          );
        })

        return (
          <div className="App">
          <h1>Choose one or more fruits</h1>
            <ul>
            { fruitOptions }
            </ul>
          </div>
        );
      }
    }

    export default App

所以基本上我可以选中和取消选中这些框,但我似乎无法更新和存储 fruitId。这也是我的复选框组件:

    import React from 'react'

    export const CheckBox = props => {
        return (
          <li>
            <input key={props.id}
              onChange={props.handleCheckChildElement}
              type="checkbox"
              id={props.id}
              checked={props.isChecked}
              value={props.value}
            />
            {props.value}
          </li>
        )
    }


    export default CheckBox

此外,如果您有比我这样做更简洁的方法来做到这一点,我很乐意看到它。

如果我要接近它,我会这样做。我将创建一个一维数组,当单击(选中)一个水果时,它保存水果的 id,我会将它的 id 添加到数组中,当它第二次单击时,我检查数组是否已经具有我将其删除的 id。那么 id 在数组中的存在将意味着水果被检查,否则它没有被检查所以我会做类似下面的事情

  this.state={
    fruitsIds: []
   }
  handleCheckChildElement=(id) => {
//the logic here is to remove the id if its already exist else add it. and set it back to state
   const fruitsIds = this.state.fruitsIds;
    this.setState({fruitsIds: fruitsIds.contains(id) ? fruitsIds.filter(i => i != id) : [...fruitsIds, id] })
   }

然后我将复选框呈现为

    <CheckBox key={index}
     handleCheckChildElement={this.handleCheckChildElement}
     isChecked = { this.state.fruitsIds.contains(fruit.id)}
     id={fruit.id}
   />

这是因为您始终可以使用 id 获取水果的所有其他属性,因此绝对不需要再次存储它们。 那么复选框组件应该如下

export const CheckBox = props => {
    return (
      <li>
        <input key={props.id}
          onChange={() => props.handleCheckChildElement(props.id)}
          type="checkbox"
          id={props.id}
          checked={props.isChecked}
          value={props.value}
        />
        {props.value}
      </li>
    )
}

您没有更新 ID 的原因是:

  1. 您正在尝试将非数组元素连接到数组。 concat 用于连接两个或多个数组。

    updatedFruitIds = fruitIds.concat(e.target.id);

  2. 您没有更新实际的 fruitIds 状态字段。我不知道你为什么要使用 "updatedFruitIds" 这个变量,但由于上述错误,它总是会导致单个元素数组。

    this.setState({ updatedFruitIds });

  updateCheckedIds = e => {
    const fruitIds = [...this.state.fruitIds],
      updatedFruitIds = fruitIds.concat([e.target.id]);
    this.setState({ fruitIds: updatedFruitIds });
  };

  updateCheckedIds = e => {
    const fruitIds = [...this.state.fruitIds, e.target.id],
    this.setState({ fruitIds });
  };