如何在反应中选中/取消选中复选框列表

Posted

技术标签:

【中文标题】如何在反应中选中/取消选中复选框列表【英文标题】:How to check/uncheck a list of checkboxes in react 【发布时间】:2018-07-09 07:12:40 【问题描述】:

我有一个room 页面,在该页面中我有一个连接到该房间的传感器列表,可以使用复选框选择这些传感器,如下所示:

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

问题是 - 这种方法禁止我取消选中该复选框(因此,如果在 db 中该传感器连接到该房间 - 就是这样)。我怎样才能重写它以便我可以选中/取消选中此复选框?

【问题讨论】:

A similar question came up yesterday. 【参考方案1】:

您有handleCheckBox 和一个受控组件。我们看不到你在事件处理程序中做了什么,但是当它被控制时,你可以通过改变你的传感器阵列(如果在状态/道具中)来检查它,所以s.roomId === values.id 将是真的。

如果您不希望它被控制,您可以使用defaultChecked,它可以让您以不同的方式使用它。

见https://reactjs.org/docs/forms.html#controlled-components

【讨论】:

我正在考虑更改状态,但是如何为无限数量的复选框列表设置默认状态? 如果你想选中/取消选中所有传感器,那么也许你需要设计一个钩子,让你覆盖房间 ID - 如果你的传感器处于状态或道具,你可以循环它们并做任何事情。见codepen.io/DimitarChristoff/pen/ZXMKKb 请记住,如果您的传感器数据发生变化,您需要拥有更多生命周期方法并将道具传播到状态。【参考方案2】:

在课堂上你必须有状态,

一个样本会有点像这样

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不好,因为you are mutating the state。 @Andy 我可以把const checkedBoxes = this.state.checkedBoxes; 改成const checkedBoxes = [...this.state.checkedBoxes];,对吧?【参考方案3】:
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;

【讨论】:

为了得到一个有用的答案,这个反应需要扩展。解释为什么这是问题的答案。

以上是关于如何在反应中选中/取消选中复选框列表的主要内容,如果未能解决你的问题,请参考以下文章

如果在该 div 中选中了所有子复选框,则选中/取消选中(全选复选框)

在 HTML5 中选中和取消选中复选框的正确方法是啥?

在纯js中选中和取消选中复选框时添加不同的确认消息

在 extjs 网格中选中复选框时如何取消突出显示该行

在Angular js中从jquery中选中还是取消选中?

access中一个表单中选中一个复选框其余的也会选中怎么解决