简体   繁体   中英

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...

You shouldn't pass anything from child to parent. Of course you can use callbacks, but you wouldn't use them to pass refs or something similar.

You just should make the Wrapper also a ForwardRef:

const Wrapper = React.forwardRef((props, ref) => {
    return <Child ref={ref} {...your other props} />
})

Now you can just call:

return someCondition ? <Wrapper ref={divElement} {...some props} /> : <Child ref={divElement} {...some props} />

and your ref will always be the div you want.

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>
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM