如何通过refs访问子组件函数

时间:2015-11-30 17:22:38

标签: javascript reactjs redux

React的文档声明组件函数可以通过refs由父组件访问。请参阅:https://facebook.github.io/react/tips/expose-component-functions.html

我试图在我的应用程序中使用它,但在调用子函数时遇到“undefined is not a function”错误。我想知道这是否与使用ES6格式的React类有关,因为我没有看到我的代码和文档之间存在任何其他差异。

我有一个Dialog组件,看起来像下面的伪代码。 Dialog有一个“Save”按钮,调用save(),需要调用子Content组件中的save()函数。 Content组件从子表单字段中收集信息并执行保存。

class MyDialog extends React.Component {
  save() {
    this.refs.content.save();                    <-- save() is undefined
  }

  render() {
    return (
      <Dialog action={this.save.bind(this)}>
        <Content ref="content"/>
      </Dialog>);
   }
}

class Content extends React.Component {
  save() {
    // Get values from child fields
    // and save the content
  }
}

我可以将prop(saveOnNextUpdate)传递给Content,然后在它为真时执行save,但我想知道如何使上面React doc中详述的方法工作。

有关如何使doc方法工作或以不同方式访问子组件的任何想法?

3 个答案:

答案 0 :(得分:51)

Redux connect接受选项参数作为第四个参数。在此选项参数中,您可以将标志withRef设置为true。然后,您可以使用getWrappedInstance()访问要引用的函数。像这样:

class MyDialog extends React.Component {
  save() {
    this.refs.content.getWrappedInstance().save();
  }

  render() {
    return (
      <Dialog action={this.save.bind(this)}>
        <Content ref="content"/>
      </Dialog>);
   }
}

class Content extends React.Component {
  save() { ... }
}

function mapStateToProps(state) { ... }

module.exports = connect(mapStateToProps, null, null, { withRef: true })(Content);

在此处详细了解:https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options

值得阅读本文关于refs的使用并考虑是否有更好的方法:https://facebook.github.io/react/docs/refs-and-the-dom.html#dont-overuse-refs

答案 1 :(得分:2)

另一种方法是使用其他一些道具名称(ref除外)。我发现,如果您使用styled-componentsemotion等库,例如在已连接的MyComponent

,这也会很有效
<MyComponent
  ...
  innerRef={(node) => { this.myRef = node; }}
/>

答案 2 :(得分:-2)

事实证明,m90是对的 - 这完全是一个不同的问题。我正在发布解决方案,以防将来有人遇到同样的问题。

我的应用程序是使用Redux构建的,问题源于使用react-redux连接函数将组件连接到存储/全局状态。出于某种原因,导出组件并将其连接到存储使得无法访问其中的功能。为了解决这个问题,我不得不从内容中删除对全局状态的所有使用,以便将其导出为“哑”组件。

更清楚的是,Content.js看起来像这样:

var connect = require('react-redux').connect;

class Content extends React.Component {
  save() {
    // Get values from child fields
    // and save the content

    // Use of this.props.stateObject
  }
}

function mapStateToProps(state) {
  const {
    stateObject
  } = state;

  return {
    stateObject
  };
}

module.exports = connect(mapStateToProps)(Content);

删除全局状态的使用(因此使用connect和mapStateToProps允许我使用以下命令导出组件:

module.exports = Content;

执行此操作后,访问this.refs.content.save()会神奇地工作。