У меня есть компонент-оболочка, который обрабатывает анимацию монтирования и размонтирования моих компонентов, а также передает любые другие реквизиты от родителя. Оболочка добавляет реквизиты class
и toggleVisibility
к дочернему элементу, чтобы я мог добавить анимацию css к содержащим элементам и изменить видимость внутри дочернего элемента, однако я хотел бы, чтобы css применялся к корневому элементу дочернего элемента без необходимости изменить код ребенка, чтобы приспособиться. Это мой код:
<Animated visibility = "initialOn" direction = "down" >
<Welcome testProp = "Coool!" />
</Animated>
export const Animated = ({
children,
visible,
direction = "up",
}: Props): JSX.Element => {
const theme: any = useTheme();
const [show, setShow] = useState(visible === "initialOn" || visible === true);
if (visible !== "initialOn" && visible !== "initialOff") {
if (show !== visible) {
setShow(visible);
}
}
const transitioned = useMountTransition(show, theme.defaultTransitionSpeed);
const toggleVisibility = () => setShow(!show);
const animatedClass = // this contains the JSS class I want to apply to the child's root element
transitioned && show
? theme.animVisible[direction]
: theme.animInVisible[direction];
const childrenWithProps = React.Children.map(children, (child) => {
if (React.isValidElement(child)) {
return React.cloneElement(child, {
toggleVisibility,
animatedClass,
});
}
return child;
});
return <>{(transitioned || show) && childrenWithProps}</>;
};
Это дочерний компонент, вы можете видеть, где я добавляю дополнительный стиль в JSS.
export const useStyles = createUseStyles<any, any>((theme: any) => {
const { modalOuter, animatedClass } = theme;
return {
splashOuter: { //container div
...modalOuter,
marginLeft: "auto",
marginRight: "auto",
...animatedClass, // apply animation styles
},
};
});
const Welcome = ({ toggleVisibility, animatedClass }: Props): JSX.Element => {
const theme = { ...useTheme(), animatedClass }; // additional styles applied within here
const styles = useStyles({ theme });
return (
<div className = {styles.splashOuter}>
<div className = {styles.splashInner}>
<button className = {styles.button} onClick = {toggleVisibility}>
PROCEED
</button>
</div>
</div>
);
};
export default Welcome;
Спасибо
Решение оказалось намного проще, чем я ожидал. Обертывание дочернего компонента в div с примененными стилями работало отлично. Спасибо
const childrenWithProps = React.Children.map(children, (child) => {
if (React.isValidElement(child)) {
return (
<div className = {styles.wrapper}>
{React.cloneElement(child, {
toggleVisibility,
})}
</div>
);
}
return child;
});
Рассматривали ли вы создание HigherOrderFunction, которая принимает любой компонент и возвращает измененный компонент с добавленным родительским элементом div с соответствующими присоединенными свойствами?