反应ES6 | 如何通过refs访问子组件函数

MKe*_*ler 35 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
  }
}
Run Code Online (Sandbox Code Playgroud)

我可以将prop(saveOnNextUpdate)传递给Content,然后在它为真时执行save,但我宁愿弄清楚如何让上面的React doc中详述的方法工作.

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

Arn*_*ekk 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);
Run Code Online (Sandbox Code Playgroud)

在这里阅读更多相关信息: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

  • string ref已弃用 (5认同)
  • 如果可以的话,我会竖起大拇指.花了几个小时寻找解决方案.这钉了它.:) (3认同)

MKe*_*ler -2

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

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

更清楚地说,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);
Run Code Online (Sandbox Code Playgroud)

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

module.exports = Content;
Run Code Online (Sandbox Code Playgroud)

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

  • connect() 函数的第三个参数确实有一个 withRef 标志,这可能是您问题的解决方案。尽管坦率地说,让父组件调用其子组件的方法似乎相当反 React。 (4认同)