如何在React中选中/取消选中一组复选框

8

我有一个 房间 页面,在该页面中,我有一个与该房间相关联的传感器列表,这些传感器可以使用复选框进行选择,如下所示:

<div className="checkboxRowContent">
  {sensors.map(s => {
    return (
      <div className="checkboxElementWrapper" key={s.id}>
        <label htmlFor={`sensor${s.id}`}>
          <div className="checkboxLabel">
            <Link to={`/sensors/edit/${s.id}`}>{s.name}</Link>
          </div>
          <input
            type="checkbox"
            id={`sensor${s.id}`}
            name="sensorId"
            value={s.id}
            checked={s.roomId === values.id}
            onChange={handleCheckbox}
          />
          <span className="checkbox" />
        </label>
      </div>
    );
  })}
</div>

问题是 - 这种方法禁止我取消复选框(因此,如果在数据库中该传感器连接到该房间 - 就是这样)。 我应该如何重写代码以便可以选择/取消该复选框?


1
昨天有一个类似的问题被提出:https://stackoverflow.com/questions/48499813/react-js-storing-an-array-of-ids-in-state。 - Andy
3个回答

4
在这个类中,你必须有状态(state)。
一个样例可能是像这样的:
```html

在这个类中,你必须有状态(state)。

一个样例可能是像这样的:

```
export default class yourComponent extends React.Component {

  state = {
    checkedBoxes: []
  }

  handleCheckbox = (e, s) => {
    const checkedBoxes = [...this.state.checkedBoxes];
    if(e.target.checked) {
      checkedBoxes.push(s)
    } else {
      const index = checkedBoxes.findIndex((ch) => ch.roomId === s.roomId);
      checkedBoxes.splice(index, 1);
    }
    this.setState({checkedBoxes});
  }


  render() {

    return(
      <div className="checkboxRowContent">
      {sensors.map(s => {
          return (
            <div className="checkboxElementWrapper" key={s.id}>
              <label htmlFor={`sensor${s.id}`}>
                <div className="checkboxLabel">
                  <Link to={`/sensors/edit/${s.id}`}>{s.name}</Link>
                </div>
                <input
                  type="checkbox"
                  id={`sensor${s.id}`}
                  name="sensorId"
                  checked={checkedBoxes.find((ch) => ch.roomId === s.roomId)}
                  onChange={(e) => handleCheckbox(e, s)}
                />
                <span className="checkbox" />
              </label>
            </div>
          );
        })}
      </div>
    )
  }
}

一个状态,checkedBoxes 用于获取所有选中的复选框。

一个处理程序 handleCheckbox 用于处理复选框的点击事件。


在这个例子中使用push不好,因为你正在改变状态。 - Andy
@Andy 我可以把 const checkedBoxes = this.state.checkedBoxes; 改成 const checkedBoxes = [...this.state.checkedBoxes];,这样可以吗? - Aswin Ramesh

2
您有一个名为handleCheckBox的处理程序和一个受控组件。我们不知道您在事件处理程序中执行了什么操作,但当它被控制时,您可以通过更改传感器数组(如果在状态/属性中)来检查它,以便s.roomId === values.id成立。
如果您不想让它受控制,您可能可以使用defaultChecked,这将让您以不同的方式处理它。
请参见https://reactjs.org/docs/forms.html#controlled-components

我在考虑更改状态,但是如何为无限数量的复选框列表设置默认状态? - Xeen
如果您想要勾选/取消所有传感器,那么也许您需要设计一个钩子来让您覆盖房间ID - 如果您的传感器处于状态或道具中,您可以循环它们并执行任何操作。请参见https://codepen.io/DimitarChristoff/pen/ZXMKKb - Dimitar Christoff
请记住,在这个例子中,如果您的传感器数据发生变化,您需要拥有更多的生命周期方法并将属性传递给状态。 - Dimitar Christoff

0
import React, {Component} from 'react';
import axios from 'axios';

const Books = props=>(

<div className='form-group'>
    <label>{props.book}
        <input type='checkbox' name={props.name}  className='form-check' onChange={props.onChange} />
    </label>
</div>
)

class Total extends Component{

constructor(props){
    super(props);

    this.onChangeCheck = this.onChangeCheck.bind(this);
    this.onSubmit = this.onSubmit.bind(this);

    this.state={
        checkBoxes: [],
        books:[]

    }
}

componentDidMount() {
    axios.get('http://localhost:3000/api/book/').then(resolve=>{
        console.log(resolve.data.data);
        this.setState({
            books:resolve.data.data
        }).catch(err=>{
            console.log(err)
        })
    })
}

onChangeCheck(e){
    console.log(e.target.name)

    if(e.target.checked){
        const array =  this.state.checkBoxes;
        array.push(e.target.name)
        this.setState({
            checkBoxes:array
        })
    }else{
        const array =  this.state.checkBoxes;
        const index = array.indexOf(e.target.name);
        console.log(index)
        array.splice(index,1);
        console.log(array);
        this.setState({
            checkBoxes:array
        })
    }
}

onSubmit(e){
    e.preventDefault();

    axios.put("http://localhost:8080/books/getTotal/",this.state.checkBoxes).then(resolve=>{
        console.log(resolve)
        alert(`Total price of books ${resolve.data}`);

    }).catch(err=>{
        console.log(err);
    })

}


render(){
    return(
        <div className='card'>
            <div className='card-header'>
            </div>
            <div className='card-body'>
                <form className='form' onSubmit={this.onSubmit}>

                    <div className='form-group'>
                        {
                            this.state.books.map(object=>(
                                    <Books name={object._id} book={object.name}  onChange={this.onChangeCheck} />
                                )
                            )
                        }
                    </div>
                    <div className='form-group'>
                        <button type='submit'  className='btn btn-success'>Get Total</button>
                    </div>
                </form>
            </div>
        </div>
    )
}
}

export default Total;

1
为了得到一个有用的回答,这个反应需要被扩展。解释为什么这是对问题的回答。 - Jeroen Heier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接