Rotareti
Rotareti

Reputation: 53813

Get DOM node of wrapped component in a higher order component (HOC)?

How do I get the DOM node of the rendered div from MyComponent inside Enhance in the following example?

Enhance.js

import { Component } from "React";

export var Enhance = ComposedComponent => class extends Component {
  constructor() {
    this.state = { data: null };
  }
  componentDidMount() {
    this.setState({ data: 'Hello' });
  }
  render() {
    return <ComposedComponent {...this.props} data={this.state.data} />;
  }
};

MyComponent.js

import { Enhance } from "./Enhance";

class MyComponent {
  render() {
    if (!this.data) return <div>Waiting...</div>;
    return <div>{this.data}</div>;
  }
}

export default Enhance(MyComponent); // Enhanced component

Upvotes: 6

Views: 1871

Answers (3)

Luca Rasconi
Luca Rasconi

Reputation: 1105

The high order component is the wrapped component itself... enhanced. Getting the dom node of the wrapped component is equivalent to get the dom node of the hoc.

export var Enhance = ComposedComponent => class extends Component {
    componentDidMount() {
        // Logs the DOM node returned by the wrapped component
        console.log( ReactDOM.findDOMNode( this ) );
    }
    render() {
        return <ComposedComponent {...this.props}  />;
    }
};

In this way I can also use forwardRef pattern

export default WrappedComponent => {
  class EnhancedComponent extends React.Component {
    constructor(props) {
      super(props);
    }

    componentDidMount() {
      const domNode = ReactDOM.findDOMNode(this);
      console.log(domNode);
    }

    render() {
      const { forwardedRef, ...otherProps } = this.props;
      return <WrappedComponent ref={forwardedRef} {...otherProps} />;
    }
  }

  const forwardRef = (props, ref) => <EnhancedComponent {...props} forwardedRef={ref} />;
  return React.forwardRef(forwardRef);
};

Upvotes: 2

thecodegoddess
thecodegoddess

Reputation: 39

findDOMNode usage appears to be frowned upon (https://github.com/yannickcr/eslint-plugin-react/issues/678#issue-165177220) and ref string values I believe will be depreciated. You can still use ref and wrap your ComposedComponent in a div with a ref, allowing you to access the node.

<div ref={ (elem) => { this.elem = elem; } }>
    <ComposedComponent { ...this.props }  />
</div>

EDIT Since you are using React Component classes, you don't need the wrapper. The wrapper is if it's a functional component.

Upvotes: 0

Andy Ray
Andy Ray

Reputation: 32066

Because your HOC is rendering a child component directly, the data returned by findDOMNode in the HOC should be the child's DOM node.

export var Enhance = ComposedComponent => class extends Component {
    componentDidMount() {
        // Logs the DOM node returned by the wrapped component
        console.log( ReactDOM.findDOMNode( this.refs.child ) );
    }
    render() {
        return <ComposedComponent {...this.props} ref="child" />;
    }
};

Upvotes: 2

Related Questions