Reactjs - 控制多个复选框

时间:2015-06-26 12:32:49

标签: checkbox reactjs

我在Reactjs中构建一个CheckAllBoxes组件。我有一个项目列表

fruits = {orange, apple, grape}

要显示和切换HTML复选框的常规<SelectBox />组件

我需要构建一个<Fruits />组件来列出所有水果,每个项目都有自己的<SelectBox />

然后我需要构建一个<SelectAll />组件,其中包含<SelectBox />,当它被选中时,它将切换<CheckBox />的所有<Fruits />

如果再次取消选中任何水果,则也应取消选中<SelectAll />

结果应如下所示:

enter image description here

如何让<SelectAll />控制其他复选框?

2 个答案:

答案 0 :(得分:8)

以下是关于如何做到这一点的简单示例:

import React, { Component } from 'react';

export default class SelectBox extends Component {
  constructor() {
    super();

    this.handleClick = this.handleClick.bind(this);
    this.state = {
      allChecked: false,
      checkedCount: 0,
      options: [
        { value: 'selectAll', text: 'Select All' },
        { value: 'orange', text: 'Orange' },
        { value: 'apple', text: 'Apple' },
        { value: 'grape', text: 'Grape' }
      ]
    };
  }

  handleClick(e) {
    let clickedValue = e.target.value;

    if (clickedValue === 'selectAll' && this.refs.selectAll.getDOMNode().checked) {
      for (let i = 1; i < this.state.options.length; i++) {
        let value = this.state.options[i].value;
        this.refs[value].getDOMNode().checked = true;
      }
      this.setState({
        checkedCount: this.state.options.length - 1
      });

    } else if (clickedValue === 'selectAll' && !this.refs.selectAll.getDOMNode().checked) {
      for (let i = 1; i < this.state.options.length; i++) {
        let value = this.state.options[i].value;
        this.refs[value].getDOMNode().checked = false;
      }
      this.setState({
        checkedCount: 0
      });
    }

    if (clickedValue !== 'selectAll' && this.refs[clickedValue].getDOMNode().checked) {
      this.setState({
        checkedCount: this.state.checkedCount + 1
      });
    } else if (clickedValue !== 'selectAll' && !this.refs[clickedValue].getDOMNode().checked) {
      this.setState({
        checkedCount: this.state.checkedCount - 1
      });
    }
  }

  render() {
    console.log('Selected boxes: ', this.state.checkedCount);

    const options = this.state.options.map(option => {
      return (
        <input onClick={this.handleClick} type='checkbox' name={option.value} key={option.value}
               value={option.value} ref={option.value} > {option.text} </input>
      );
    });


    return (
      <div className='SelectBox'>
        <form>
          {options}
        </form>
      </div>
    );
  }
}

我很抱歉ES6的例子。当我找到更多时间时会添加ES5示例,但我认为您可以了解如何做到这一点。 另外你肯定想把它分解为2个组件。然后,您只需将选项作为道具传递给子组件。

答案 1 :(得分:0)

我建议阅读Communication between Components

现在,在您的示例中,您将在两个没有父子关系的组件之间进行通信。在这些情况下,您可以使用全局事件系统。 Flux与React配合得很好。

在您的示例中,我将使用组件FruitStore监听存储来FruitFruitStore包含一个列表,其中包含所有水果以及是否选中它们。 Fruit将使用setState()保存其内容。

Fruit将每个道具的状态传递给它的孩子。例如:<CheckBox checked={this.state.fruit.checked} name={this.state.fruit.name}/>

单击Checkbox时,

FruitAction.checkCheckbox(fruitName)会触发。

然后FruitStore将更新Fruit组件,依此类推。

进入这种单向架构需要一些时间,但值得学习。尝试从Flux Todo List Tutorial开始。