Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 405
MKeller Avatar asked Nov 30 '15 17:11

MKeller


People also ask

How do you use REF in child components?

Creating Refs Refs are created using React. createRef() and attached to React elements via the ref attribute. Accessing Refs When we assign a ref to an element or child component in the render, then we can access the element using the current attribute of the ref. const element = this.

How do you pass ref to child component React hooks?

The forwardRef hooks allows React users to pass refs to child components. The ref can be created and referenced with useRef or createRef and then passed in a parent component. Using forwardRef instead of useRef is useful when a ref needs to be accessed in a parent component.

Can we pass ref to functional component?

Function components don't have ref attribute because they don't have instances like class components. Therefore you must FORWARD THE REF to any other element within it. You can't use the ref prop as it reserved.


Video Answer


2 Answers

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

like image 195
Arne H. Bitubekk Avatar answered Sep 23 '22 11:09

Arne H. Bitubekk


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; }}
/>
like image 29
Divyanshu Maithani Avatar answered Sep 25 '22 11:09

Divyanshu Maithani