React v16 — передать ссылку от дочернего к родительскому через компонент-оболочку

У меня есть существующая иерархия компонентов, которая выглядит так:

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

Это все хорошо, но теперь мне нужно условно добавить компонент-оболочку, который обертывает компонент <Child>, чтобы добавить некоторые реквизиты для особых случаев.

В основном я хочу что-то вроде этого:

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

Я застрял на том, как передать ref от Child через Wrapper обратно к Parent, чтобы Parent мог получить доступ к Child ref независимо от того, есть Wrapper или нет...


person szeryf    schedule 07.08.2020    source источник
comment
Оберните компонент Wrapper компонентом React.forwardRef(). Демо   -  person Yousaf    schedule 07.08.2020


Ответы (2)


В дополнение к использованию React.forwardRef, как сказал @Reductio, вы можете использовать пользовательские реквизиты для передачи ссылки дочерним элементам, независимо от того, с помощью Wrapper или нет.

Я узнал об этом отсюда: https://deniapps.com/blog/clarify-react-ref-by-examples Передача ref через пользовательские пропсы намного проще. Код нравится это:

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

person Adam C.    schedule 09.08.2020
comment
Это, конечно, рабочее решение. Я бы всегда предпочитал использовать прямые ссылки, потому что это обычный способ обработки ссылок в реакции, и у вас есть фиксированный протокол для передачи ссылок. Тем не менее, это больше похоже на руководство, которому вы можете следовать, но не обязаны. - person Reductio; 10.08.2020

Вы не должны ничего передавать от ребенка к родителю. Конечно, вы можете использовать обратные вызовы, но вы не будете использовать их для передачи ссылок или чего-то подобного.

Вам просто нужно сделать Wrapper также ForwardRef:

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

Теперь вы можете просто позвонить:

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

и ваш ref всегда будет тем div, который вы хотите.

person Reductio    schedule 07.08.2020