简体   繁体   中英

How to access child component functions via refs

The docs for React state that component functions can be accessed by a parent component via refs. See: https://facebook.github.io/react/tips/expose-component-functions.html

I am attempting to use this in my application but run into an "undefined is not a function" error when the child function is called. I'm wondering if this has anything to do with using the ES6 format for React classes because I don't see any other differences between my code and the docs.

I have a Dialog component that looks like the following pseudocode. The Dialog has a "Save" button that calls save(), which needs to call the save() function in the child Content component. The Content component collects information from child form fields and performs the save.

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
  }
}

I could instead pass a prop (saveOnNextUpdate) down to Content and then execute save whenever it is true, but I would rather figure out how to get the method detailed in the React doc above to work.

Any ideas on how to get the doc approach to work or access the child component function in a different way?

Redux connect accepts an option parametre as the forth parameter. In this option parameter you can set the flag withRef to true. Then you can access functions to refs by using getWrappedInstance(). Like this:

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);

Read more about it here: https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options

Worth reading this article about use of refs and consider if there's better approaches: https://facebook.github.io/react/docs/refs-and-the-dom.html#dont-overuse-refs

An alternative way to do this would be to use some other prop name (other than ref ). I've found that this also works well if you're using a library like styled-components or emotion For example in a connected MyComponent :

<MyComponent
  ...
  innerRef={(node) => { this.myRef = node; }}
/>

As it turns out, m90 was right -- this was a different issue entirely. I'm posting the solution in case someone runs into the same problem in the future.

My application is built with Redux, and the problem stems from using the react-redux connect function to connect a component to the store/global state. For some reason, exporting a component and connecting it to the store makes it impossible to access the functions inside of it. In order to get around this, I had to remove all use of global state from Content so that I could export it as a "dumb" component.

To be more clear, Content.js looked like this:

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);

Removing the use of global state (and therefore the use of connect and mapStateToProps allowed me to export the component using:

module.exports = Content;

Accessing this.refs.content.save() magically worked after doing this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM