Search code examples
javascriptreactjsrefreact-forwardref

React v16 – pass ref from child to parent through a wrapper component


I have an existing component hierarchy that looks like this:

const Parent = props => {
  const divElement = useRef()
  // do something with divElement
  return <Child ref={divElement} {...some props} />
}

const Child = React.forwardRef((props, ref) => {
  return <div ref={ref}><some stuff here></div>
}

This is all fine, but now I need to conditionally add a wrapper component, which wraps the <Child> component to add some special case props.

Basically what I want is something like this:

const Parent = props => {
  const divElement = useRef()
  // do something with divElement
  return someCondition ? <Wrapper {...some props} /> : <Child ref={divElement} {...some props} />
}

const Wrapper = props => {
  return <Child {...different props} />
}

const Child = React.forwardRef((props, ref) => {
  return <div ref={ref}><some stuff here></div>
}

I'm stuck on how to pass the ref from Child through the Wrapper back to Parent, so the Parent can access the Child's ref no matter whether the Wrapper is there or not...


Solution

  • In addition to using React.forwardRef like @Reductio said, you could use custom props to pass down the ref to the children whether with the Wrapper or not.

    I learned this from here: https://deniapps.com/blog/clarify-react-ref-by-examples Passing ref via custom props is much simpler. The code likes this:

    const Parent = props => {
      const divElement = useRef()
      // do something with divElement
      return someCondition ? <Wrapper {...some props} forwardedRef={divElement} /> : <Child forwardedRef={divElement} {...some props} />
    }
    
    const Wrapper = props => {
      //MAKE SURE "different props" includes the custom props: forwardedRef from props
      return <Child {...different props} />
    }
    
    const Child =({forwardRef, ...rest}) => {
      return <div ref={forwardedRef} {...rest}><some stuff here></div>
    }