使用React子组件进行封装

时间:2015-06-15 08:11:15

标签: coding-style reactjs encapsulation

如何在React中访问子组件的状态(只是状态,而不是React State)?

我已经构建了一个小型的React UI。在其中,我有一个组件显示所选选项的列表和一个允许编辑它们的按钮。单击该按钮将打开一个带有一系列复选框的模态,每个选项对应一个。 Modal是它自己的React组件。显示所选选项的顶级组件和编辑它们的按钮拥有状态,Modal使用props渲染。一旦模态被解除,我想获得复选框的状态以更新父对象的状态。我这样做是通过使用refs来调用子对象'getSelectedOptions'上的一个函数,它返回一些JSON,用于识别所选的选项。因此,当选择模态时,它会调用从父项传入的回调函数,然后向模态调用所选的新选项集。

这是我的代码的简化版本

OptionsChooser = React.createClass({
  //function passed to Modal, called when user "OK's" their new selection
  optionsSelected: function() {
    var optsSelected = this.refs.modal.getOptionsSelected();
    //setState locally and save to server...
  },

  render: function() {
    return (
      <UneditableOptions />
      <button onClick={this.showModal}>Select options</button>
      <div>
        <Modal 
          ref="modal" 
          options={this.state.options} 
          optionsSelected={this.optionsSelected} 
        />
      </div>
      );
  }
});

Modal = React.createClass({
  getOptionsSelected: function() {
    return $(React.findDOMNode(this.refs.optionsselector))
      .find('input[type="checkbox"]:checked').map(function(i, input){
        return {
          normalisedName: input.value
        };
      }
     );
   },

  render: function() {
    return (
      //Modal with list of checkboxes, dismissing calls optionsSelected function passed in
    );
  }
});

这使得Modal的UI的实现细节从父级隐藏,这在我看来是一个很好的编码实践。但是我被告知以这种方式使用ref可能是不正确的,我应该以其他方式传递状态,或者确实让父组件访问复选框本身。我还是比较新的React,所以想知道在这种情况下是否有更好的方法?

1 个答案:

答案 0 :(得分:2)

是的,你真的不想这样使用refs。相反,一种方法是将回调传递给模态:

OptionsChooser = React.createClass({
  onOptionSelect: function(data) {

  },

  render: function() {
    return <Modal onClose={this.onOptionSelect} />
  }
});

Modal = React.createClass({

  onClose: function() {
    var selectedOptions = this.state.selectedOptions;
    this.props.onClose(selectedOptions);
  },

  render: function() {
    return ();
  }
});

即,孩子调用通过道具传递的函数。此外,您获得所选选项的方式看起来过于挑剔。相反,您可以使用勾选复选框时运行的函数,并将选择存储在模态状态。

此问题的另一个解决方案可能是使用Flux模式,其中您的子组件触发带有数据的操作并将其中继到商店,您的顶级组件将听取该商店。但这有点超出了这个问题的范围。