Я создаю анимацию раскрытия/свертывания, мне нужно получить доступ к высоте анимированного элемента. Поэтому мне нужна его ссылка внутри компонента, который выполняет анимацию (с именем CollapseTransition
). Я могу передать ref
, создав его в родительском компоненте и перенаправив его в компонент анимации, но, на мой взгляд, это слишком много кода, я бы не хотел писать javascript при использовании моего компонента анимации.
Есть ли способ получить доступ к ref
из children
исключительно в компоненте CollapseTransition
, который я создал?
const refTransitionnedElement = useRef(null);
return (
<div>
<CollapseTransition visible = {visible} ref = {refTransitionnedElement}>
<div ref = {refTransitionnedElement}>test</div>
</CollapseTransition>
</div>
);
export const CollapseTransition = forwardRef((props: { visible: boolean; children: any; }, ref) => {
//[...]
return (
<>[...]</>
);
});
В конечном счете, я хотел бы использовать свой компонент CollapseTransition
следующим образом:
<CollapseTransition visible = {visible}>
<div>test</div>
</CollapseTransition>
Имея доступ к высоте div в моем компоненте CollapseTransition
.
Я думаю, что вы должны использовать шаблон Render Props здесь.
export const CollapseTransition = (props: { visible: boolean; children: any; }) => {
const refTransitionnedElement = useRef(null);
return (
<>{children(refTransitionnedElement)}</>
);
});
И вы используете его таким образом.
return (
<div>
<CollapseTransition visible = {visible}>
{(refTransitionnedElement) => (
<div ref = {refTransitionnedElement}>test</div>
)}
</CollapseTransition>
</div>
);
Или вы можете использовать React.children.map (шаблон составных компонентов).
export const CollapseTransition = (props: { visible: boolean; children: any; }) => {
const refTransitionnedElement = useRef(null);
return (
<>{React.Children.map(children, (child) => {
return React.cloneElement(child, {
ref: refTransitionnedElement
});
})}</>
);
});
И использовать его таким образом
<CollapseTransition visible = {visible}>
<div>test</div>
</CollapseTransition>
В этом решении составных компонентов вам необходимо убедиться, что существует только один дочерний элемент элемента CollapseTransition.
Попробуй сейчас. Я исправил вызов react.children.map. Первый аргумент должен быть дочерним массивом :)
Спасибо, мне удалось протестировать его в изолированном компоненте, и он работает. К сожалению, когда я применяю переходы с помощью пакета react-transition-group
, я не могу клонировать компоненты, так как он выдает всевозможные ошибки.
Ваше первое решение работает, второе выглядит еще лучше, но мне не удается заставить его работать. Похоже, вы неправильно реализовали функцию карты.