1

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

6
  • 3
    could you maybe provide some code in codesandbox or some similar service? Commented Aug 24, 2018 at 12:56
  • You can pass ref as a prop. Have you tried it? Commented Aug 24, 2018 at 13:03
  • @devserkan You cannot since the creator is a regular fucntions, React doesnt allow it Commented Aug 24, 2018 at 13:17
  • @LazarNikolic codesandbox.io/s/lyj6x2948m Commented Aug 24, 2018 at 13:17
  • edit your question to include codesandbox Commented Aug 24, 2018 at 13:25

2 Answers 2

1

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:

Sign up to request clarification or add additional context in comments.

3 Comments

I mean there are monumental differences between your example and what I described, for one, you are reacting to an event fired from a child, obviously, you can reference the child from within itself and only pass it back to the parent for what the parent wants to do with it. This example doesn't really illustrate the problem at all, neither of them. The event-trigger needs to happen on a parent element, and child has to be focused, and since focus is not a property it kind-of is not passable, to my knowledge, check the codesandbox link i made.
Secondly you are instantiating a child as a class, where as I am using a plain old javascript function to generate a react component and return it as a child, which could pass the ref as a prop, if that was to be done by react, but its not. If you have a better solution im open to suggestions
I've misunderstood your question and I'm sorry for that. Working on improved solution =)
1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.