React - 将组件函数暴露给它的子元素

时间:2016-08-10 07:13:10

标签: javascript reactjs

所以我试图创建一种抽象的框架'对于不同的部分,我将在我的网站上重复使用。

所以现在我正在研究一个模态,它包括:

  • 标题
  • 其内容
  • 动作(取消,保存等按钮)

我想写的方式是:

<Modal> // <- This wrapper contains different functions for controlling the entire modal.
  <ModalTitle>Editing</ModalTitle>
  <ModalContent>
    <form>
      <input type="text"/>
    </form>
  </ModalContent>
  <ModalActions/> // <- This one is empty since I already have save buttons as a default for it.
</Modal>

这将允许我更改每个模态的内容,标题和添加特定操作,这里是不同部分的一些代码:

var Modal = React.createClass({
  close: function() {
    this.props.onUserClose();
  },
  save: function() {
    // validates inputs from a form, sends it back, and closes the modal
  },
  render: function() {
    return (
      <dialog className="mdl-dialog" ref="modal">
        <button
          type="button"
          className="mdl-button mdl-js-button mdl-button--icon helper-modal-button--close"
          onClick={this.close}  
        >
          <i className="material-icons">clear</i>
        </button>
        {this.props.children}
      </dialog>
    );
  }
};

标题非常简单,但这会抽象出类名,如果需要,可以在里面添加不同的内容。

var ModalTitle = React.createClass({
  render: function() {
    return (
      <h2 className="mdl-dialog__title">{this.props.children}</h2>
    );
  }
});

内容与标题几乎相同。

var ModalContent = React.createClass({
  render: function() {
    return (
      <div className="mdl-dialog__content">
        <form id="modal-form">{this.props.children}</form>
      </div>
    );
  }
});

现在我需要采取行动,以及需要帮助的地方:

var ModalActions = React.createClass({
  render: function() {
    return (
      <div className="mdl-dialog__actions">
        <button type="button" className="mdl-button" onClick={this.save}>Save</button>
        {this.props.children}
      </div>
    );
  }
});

现在,正如你所看到的,我已经为动作添加了一个保存动作,因为我想在每个模态上都有它,但问题在于如何访问保存功能?我不认为我可以把它作为父母的道具传递,我想我必须拦截它的孩子,检查它并给它一个支撑它的保存功能,但我找不到任何好处关于如何正确地做到这一点的信息,而不是如何识别其中一个孩子是哪一个。

我认为最好的另一种方法是,如果我可以将保存功能公开给所有孩子,并且只对保存动作采取行动。这也可以让我编写利用“API”的自定义操作。

尽管如此,还没有找到关于我如何做到这一点的任何好消息,任何想法?

1 个答案:

答案 0 :(得分:1)

您可以使用React.Children迭代子项,然后使用React.cloneElement

使用新道具(浅合并)克隆每个元素
render: function() {
    const childrenWithProps = React.Children.map(this.props.children,
     (child) => React.cloneElement(child, {
       doSomething: this.doSomething
     })
    );

    return <div>{childrenWithProps}</div>
  }