封装 React 子组件

Encapsulation with React child components

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

我构建了一个小型 React UI。在其中,我有一个显示所选选项列表的组件和一个允许编辑它们的按钮。单击该按钮会打开一个带有一堆复选框的模式,每个选项一个。 Modal 是它自己的 React 组件。显示所选选项和编辑它们的按钮的顶级组件拥有状态,而 Modal 则使用道具呈现。一旦 Modal 被取消,我想获取复选框的状态以更新父对象的状态。我这样做是通过使用 refs 在子对象 'getSelectedOptions' 上调用一个函数,其中 returns 一些 JSON 对我来说识别了那些选择的选项。 So when the Modal is selected it calls a callback function passed in from the parent which then asks the Modal for the new set of options selected.

这是我的代码的简化版本

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 的实现细节,在我看来这是一个很好的编码习惯。然而,我被告知以这种方式使用 refs 可能是不正确的,我应该以其他方式传递状态,或者实际上让父组件访问复选框本身。我对 React 还是比较陌生,所以想知道在这种情况下是否有更好的方法?

是的,您真的不想像这样使用 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 ();
  }
});

即 child 调用一个通过 props 传入的函数。此外,您获得所选选项的方式看起来 over-fussy。相反,您可以拥有一个在复选框被选中时运行的函数,并将选择存储在模态状态中。

此问题的另一种解决方案可能是使用 Flux 模式,其中您的 child 组件触发一个带有数据的操作并将其中继到存储,您的 top-level 组件将监听该存储.不过,这有点超出了这个问题的范围。