Dellirium
Dellirium

Reputation: 1516

React ref a nested component

I ran into an issue which I do not know how to "properly" solve.

I have two components, let's call them parent and child.
child component is "generated" by a call to a function that creates it, let's call this function child creator. parent component has a button which shows/hides the child but is also suppose to .focus() the HTML dom node which is what the child is. Now the show/hide I implemented via the state, but I do not know how to apply javascript's .focus() onto the child's HTML dom node.

There is also a small catch... the child component is being "generated" and "returned" by a call to a plain old javascript function, let's call it createChild.

This is due to the fact that child component needs to be vastly different based on what the parameters that were passed are, however, it also needs to be reused throughout the application so the createChild functions make sure that all the child components are the same, given the same inputs.

I tried passing ref to the creator, however since ref is not a prop, it is not accessible. What is the proper way to "grab" the children's dom nodes in order to .focus() them when the button is clicked since I cannot pass a ref?

Code sandbox link: https://codesandbox.io/s/lyj6x2948m

Upvotes: 1

Views: 9091

Answers (2)

Dellirium
Dellirium

Reputation: 1516

Okay for everyone wondering, I found a solution to the problem. To begin with, the issue was not in the ref passing (at least not explicitly), but rather in a way controls are being created (which doesnt allow the ref to be passed).

The controlCreator function is a good old simple javascript function, and it was being used to provide a type for a React.createElement because the result of calling the controlCreator ends up being a react component.
I have however came to an understanding of why this is wrong and have instead proceeded to generate my child elements by the controlCreator and then using React.cloneElement to inject them with a ref. This way, the element is being cloned within a parent and can thus be referenced by parent's methods.

A link to a working code sandbox

Upvotes: 1

Canta
Canta

Reputation: 1480

Yes, child ref is accessible since it is part of real DOM. I made a simple example with two nested components, check it out:

class Parent extends React.Component {
  focusRef(ref) {
    ref.focus();
  }
  
  render() {
    return <Child focusRef={this.focusRef} />
  }
};

class Child extends React.Component {
  render() {
    return (
      <button 
        ref={childRef => this.childRef = childRef}
        onMouseEnter={() => this.props.focusRef(this.childRef)}
      >
        When mouse enters, i get focused
      </button>
    );
  }  
}

ReactDOM.render(
  <Parent />,
  document.getElementById("root")
);
*:focus {
  outline: 2px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root" />

Also, I strongly recommend further reading on react docs:

Upvotes: 1

Related Questions