2

Apparently this is not possible, but since I'm not a React expert I'd like to get a confirmation.

The usual way of getting the DOM element of a child is with:

render () {
    const child = React.Children.only(this.props.children);
    const cloned = React.cloneElement(child, {
        ref: this.someRef
    });
    return cloned;
}

The problem here is that according to the docs:

You may not use the ref attribute on function components because they don’t have instances

Another option to find the DOM element could be using React.findDOMNode() but according to a comment from this issue when trying to React.findDOMNode(child):

If you want to find one of your children's DOM nodes, you have to add a ref first (using React.cloneElement) and then use that ref.

And we're back to the previous problem.

So, is it possible to find the DOM element of a functional component?

Pier
  • 10,298
  • 17
  • 67
  • 113

1 Answers1

0

As suggested in this question, this may be one of few acceptable cases for calling stateless component function directly:

function withRef(SFC) {
  return React.forwardRef((props, ref) => SFC({ref, ...props}));
}

...

render () {
  const child = React.Children.only(this.props.children);
  const isFunctional = typeof child === 'function' &&
    (!child.prototype || !child.prototype.isReactComponent);

  if (isFunctional) {
    const Child = withRef(child.type);

    return <Child {...child.props} ref={this.someRef}/>;
  } else {
    ...
  }
}

This won't work if functional component's child cannot accept a ref, too.

In this form it's inefficient because a child will be re-rendered. Depending on what's the purpose, there may be better ways to achieve this. A component could be designed to receive a component to render as a prop instead of a child. Or if DOM element is needed for specific task like setting up DOM event listener, this may be done like in this case .

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • AFAIK this doesn't work either because (like you said) no refs can used – Pier Oct 24 '18 at 21:12
  • Did you try it? withRef specifically allows to pass refs to stateless components. *this may be one of few acceptable cases for calling stateless component function directly*. – Estus Flask Oct 25 '18 at 06:10