1

The title is pretty straightforward, I need to access a property (a ref to be precise) on a child element that is passed through the children of my component, which means that I can't pass the ref in the parent afaik. Here's a minimal example to highlight my issue:

import React from "react";

class Child extends React.Component {
  myRef = React.createRef();

  render() {
    return <div ref={this.myRef}>child</div>;
  }
}

const Parent = ({ children }) => {
  const myChild = React.Children.toArray(children).find(
    child => child.type === Child
  );
  // I want to access this
  console.log(myChild.myRef);
  // but it's undefined

  return (
    <div>
      <h1>Parent</h1>
      {children}
    </div>
  );
};

// I can't really change this component
export default function App() {
  return (
    <div className="App">
      <Parent>
        <Child />
      </Parent>
    </div>
  );
}

I made a codesandbox highlighting my issue https://codesandbox.io/s/eloquent-wing-e0ejh?file=/src/App.js

reactnoob
  • 11
  • 1
  • 1
    Does this answer your question? [How do I access refs of a child component in the parent component](https://stackoverflow.com/questions/37647061/how-do-i-access-refs-of-a-child-component-in-the-parent-component) – jogesh_pi Jun 15 '20 at 09:40
  • 1
    Would you elaborate a bit what is it you're trying to achieve? Chances are passing Refs to parent component is not what you really need. – Yevhen Horbunkov Jun 15 '20 at 09:41
  • @jogesh_pi nope because the Child isn't set in Parent unfortunately – reactnoob Jun 15 '20 at 09:47
  • @YevgenGorbunkov I need to access the Child's dom element inside Parent because I need to check its height/scrollPosition & match it with the Parent – reactnoob Jun 15 '20 at 09:47
  • Then you may [lift](https://reactjs.org/docs/lifting-state-up.html) child `height`/`scrollPosition` while handling `onScroll` to your parent's state. Refs [are not](https://reactjs.org/docs/refs-and-the-dom.html#dont-overuse-refs) the key to every door in React. If you would share some code sample *closer* to your real case, I would suggest some relevant code to solve your problem. – Yevhen Horbunkov Jun 15 '20 at 09:57
  • This looks like @jogesh_pi solution but I don't have access to App, only Parent & Child so I can't lift child's data. And if I want to use ref it's because the calculation I have to do are quite heavy and I don't want rerenders so I can't use context/redux – reactnoob Jun 15 '20 at 10:05

1 Answers1

2

Rather than declaring ref in <Child/>, you should declare ref in your <Parent/> and pass it to the child.

import React from "react";

class Child extends React.Component {

  render() {
    return <div ref={this.props.myRef}>child</div>;
  }
}

const Parent = ({ children }) => {
  const myRef = React.useRef(null);

  // access it from here or do other thing
  console.log(myRef);

  return (
    <div>
      <h1>Parent</h1>
      { children(myRef) }
    </div>
  );
};

export default function App() {
  return (
    <div className="App">
      <Parent>
        {myRef => (
          <Child myRef={myRef} />
        )}
      </Parent>
    </div>
  );
}

bonnopc
  • 755
  • 1
  • 7
  • 19