【问题标题】:Reactjs - Controlling Multiple CheckboxesReactjs - 控制多个复选框
【发布时间】:2015-09-13 09:55:41
【问题描述】:

我在 Reactjs 中构建一个 CheckAllBoxes 组件。我有一个物品清单

fruits = {orange, apple, grape}

一个通用的<SelectBox /> 组件,用于显示和切换 HTML 复选框

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

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

如果再次取消选中任何水果,那么 <SelectAll /> 也应该取消选中。

结果应该是这样的:

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

【问题讨论】:

    标签: checkbox reactjs


    【解决方案1】:

    我会推荐阅读Communication between Components

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

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

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

    Checkbox 应在单击 FruitAction.checkCheckbox(fruitName) 时触发。

    然后FruitStore 将更新Fruit 组件等等。

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

    【讨论】:

    • 我认为为此使用助焊剂太过分了。在Fruit 组件中拥有状态还有什么意义?如果你想使用 Flux,那么你可以将你的数据放在 FruitStore 中,并在 props 中传递给 Fruit 组件...
    【解决方案2】:

    下面是一个简单的例子:

    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 个组件。然后,您只需将您的选项作为道具传递给子组件。

    【讨论】:

      猜你喜欢
      • 2019-02-13
      • 1970-01-01
      • 2016-11-22
      • 2019-10-13
      • 1970-01-01
      • 2021-09-09
      • 2016-12-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多