模块化和抽象反应组件功能

时间:2015-09-18 05:49:43

标签: javascript html checkbox reactjs components

我有一个工作组件,它允许一个复选框all和复选框。它完美地运作。但是我讨厌我每次想要使用这个功能时都被困在所有这些代码中的想法。我正在寻找一种方法来做出这种模块化的方法吗?这是

它不会在一个地方模块化“输入全部检查”功能的整个功能。我必须在每次使用时移动getInitialState变量和changeHandlers。

我认为如果“输入复选框全部”功能在HTML中是原生的,我们将如何使用它?我们只需要为元素提供属性,它们会相互引用,所有处理程序都会在引擎盖下发生,使用起来会很简单。我的这个例子的目标是让HTML级别简单。我上面展示的代码没有实现,因为它与功能处理程序和状态初始化程序相关联。反应是否提供了一种抽象方式?

以下是此组件所需的API。

Here's the working example.

主要问题是:

  • 组件功能与父级无关,这意味着不需要为处理程序和状态存储信息。
  • 当前代码手动跟踪每个复选框的状态,这意味着无法动态查找DOM中有多少复选框而没有说明它。
  • 整体模块化和易用性。

以下是代码:

var InputCheckbox = React.createClass({
  getDefaultProps: function () {
    return {
      checked: false
    }
  },
  render: function () {
    return (
    <input
           checked={this.props.checked}
           type='checkbox'
           {...this.props}/>
    )
  }
})

var Test = React.createClass({
  getInitialState: function () {
    return {
      checked: [false, false, false]
    }
  },
  selectAll: function (event) {
    // Set all checked states to true
    this.setState({
      checked: this.state.checked.map(function () {
        return event.target.checked
      })
    })
  },
  handleChange: function (index, event) {
    var checked = this.state.checked
    checked[index] = event.target.checked
    this.setState({
      checked: checked
    })
  },
  render: function () {
    var isAllChecked = this.state.checked.filter(function (c) {
        return c
      }).length === this.state.checked.length

    return (
    <div>
      Select All:
      <InputCheckbox onChange={this.selectAll} checked={isAllChecked}/>
      <br/>
      <InputCheckbox checked={this.state.checked[0]} onChange={this.handleChange.bind(this, 0)}/>
      <br/>
      <InputCheckbox checked={this.state.checked[1]} onChange={this.handleChange.bind(this, 1)}/>
      <br/>
      <InputCheckbox checked={this.state.checked[2]} onChange={this.handleChange.bind(this, 2)}/>
      <br/>
    </div>
    )
  }
})

React.render(<Test/>, document.body)

理想情况下,我可以像这样使用它:

var Checkbox = require('./Checkbox')

var Test = React.createClass({
  render: function () {
    return (
      <div>
        <Checkbox id="alpha"/>
        <Checkbox htmlFor="alpha"/>
        <Checkbox htmlFor="alpha"/>
        <Checkbox htmlFor="alpha"/>
      </div>
    )
  }
})

1 个答案:

答案 0 :(得分:0)

我使用一些jQuery和lodash一起攻击了这个。

Here's the example running.

注意,此示例进入DOM以获取所需的数据。这些复选框的状态都不是由组件存储的。据我所知,没有真正的&#34; React&#34;这样做的方式。 (我很乐意接受建议。)

var Checkbox = React.createClass({
  componentDidMount: function () {
    var component = React.findDOMNode(this)
    var $component = $(component)
    if ($component.attr('id')) {
      var selector = 'input'
      selector += '[data-component=Checkbox]'
      selector += '[for=' + $component.attr('id') + ']'
      var $forComponents = $(selector)
      $component.on('change', function () {
        var value = $component.prop('checked')
        $forComponents.each(function () {
          $forComponent = $(this)
          $forComponent.prop('checked', value)
        })
      })
      $forComponents.on('change', function () {
        var values = $forComponents.map(function () {
          var $forComponent = $(this)
          var value = $forComponent.prop('checked')
          return value
        })
        var simple = _.chain(values).unique().value()
        if (simple.length === 1 && simple[0] === true) {
          $component.prop('checked', true)
        } else {
          $component.prop('checked', false)
        }
      })
    }
  },
  render: function () {
    return (
    <input
       type='checkbox'
       data-component='Checkbox'
       {...this.props}/>
    )
  }
})

var Test = React.createClass({
  render: function () {
    return (
    <div>
      Select All: <Checkbox id='alpha'/><br/>
      <Checkbox htmlFor='alpha'/><br/>
      <Checkbox htmlFor='alpha'/><br/>
      <Checkbox htmlFor='alpha' defaultChecked/><br/>
      <Checkbox htmlFor='alpha'/><br/>
      <Checkbox htmlFor='alpha'/><br/>
    </div>
    )
  }
})

React.render(<Test/>, document.body)