反应过渡组没有动画
react-transition-group does not animate
我使用 React 和 tranct-transition-group 编写轮播组件
但是遇到了动画不生效的问题。代码如下
Link https://stackblitz.com/edit/react-ts-mi8mwj?file=Carousel.tsx
Carousel.tsx
import React, { FC, Fragment, ReactNode, useMemo, useState } from 'react';
import { CSSTransition, TransitionGroup } from 'react-transition-group';
import CarouselItem, { ItemProps } from './CarouselItem';
import './Carousel.scss';
export interface Props {}
const Component: FC<Props> = (props) => {
const { children } = props;
const [curIndex, setCurIndex] = useState(1);
const length = useMemo(() => {
return Array.from(children as ReactNode[]).length;
}, [children]);
const onNext = () => {
setCurIndex((curIndex + 1 + length) % length);
};
const onPrev = () => {
setCurIndex((curIndex - 1 + length) % length);
};
return (
<Fragment>
<button onClick={onPrev}>prev</button>
<button onClick={onNext}>next</button>
<div className="g-carousel-wrapper">
<div className="g-carousel-window">
<TransitionGroup className="item">
{React.Children.map(children, (child, index) => {
const childElement = child as FC<ItemProps>;
if(child.type !== CarouselItem) throw new Error('必须是Item')
return (
<CSSTransition classNames="item" timeout={300} key={index}>
{React.cloneElement(childElement, {
index,
style: { display: curIndex !== index && 'none' },
})}
</CSSTransition>
);
})}
</TransitionGroup>
</div>
</div>
</Fragment>
);
};
type CarouselType = {
Item: FC<ItemProps>;
} & FC<Props>;
const Carousel: CarouselType = Component as CarouselType;
Carousel.Item = CarouselItem;
export default Carousel;
CarouselItem.tsx
import React, { CSSProperties, FC } from 'react';
export interface ItemProps {
index?: number;
style?: CSSProperties;
}
const carouselItem: FC<ItemProps> = (props) => {
const { children, style } = props;
return (
<div className="g-carousel-item" style={style}>
{children}
</div>
);
};
export default carouselItem;
不明白为什么不仅没有动画效果而且CSSTransition的className也不存在,好像react-transition-group没有生效谢谢
我认为我们不需要使用 TransitionGroup
组件。 CSSTransition
本身支持一个in
属性,我们可以使用这个属性来控制它的可见性。
所以首先,将 in
条件添加到 CSSTransition
:
<CSSTransition
in={curIndex === index}
classNames="item"
timeout={300}
key={index}
>
然后,只需删除 TransitionGroup
:
<div className="g-carousel-wrapper">
<div className="g-carousel-window">
{React.Children.map(children, (child, index) => {
const childElement = child as FC<ItemProps>;
if (child.type !== CarouselItem) throw new Error('必须是Item');
return (
<CSSTransition
in={curIndex === index}
classNames="item"
timeout={300}
key={index}
>
{React.cloneElement(childElement, {
index,
style: { display: curIndex !== index && 'none' },
})}
</CSSTransition>
);
})}
</div>
</div>
它现在应该可以工作了:https://stackblitz.com/edit/react-ts-kqed2n?file=Carousel.tsx
我使用 React 和 tranct-transition-group 编写轮播组件
但是遇到了动画不生效的问题。代码如下
Link https://stackblitz.com/edit/react-ts-mi8mwj?file=Carousel.tsx
Carousel.tsx
import React, { FC, Fragment, ReactNode, useMemo, useState } from 'react';
import { CSSTransition, TransitionGroup } from 'react-transition-group';
import CarouselItem, { ItemProps } from './CarouselItem';
import './Carousel.scss';
export interface Props {}
const Component: FC<Props> = (props) => {
const { children } = props;
const [curIndex, setCurIndex] = useState(1);
const length = useMemo(() => {
return Array.from(children as ReactNode[]).length;
}, [children]);
const onNext = () => {
setCurIndex((curIndex + 1 + length) % length);
};
const onPrev = () => {
setCurIndex((curIndex - 1 + length) % length);
};
return (
<Fragment>
<button onClick={onPrev}>prev</button>
<button onClick={onNext}>next</button>
<div className="g-carousel-wrapper">
<div className="g-carousel-window">
<TransitionGroup className="item">
{React.Children.map(children, (child, index) => {
const childElement = child as FC<ItemProps>;
if(child.type !== CarouselItem) throw new Error('必须是Item')
return (
<CSSTransition classNames="item" timeout={300} key={index}>
{React.cloneElement(childElement, {
index,
style: { display: curIndex !== index && 'none' },
})}
</CSSTransition>
);
})}
</TransitionGroup>
</div>
</div>
</Fragment>
);
};
type CarouselType = {
Item: FC<ItemProps>;
} & FC<Props>;
const Carousel: CarouselType = Component as CarouselType;
Carousel.Item = CarouselItem;
export default Carousel;
CarouselItem.tsx
import React, { CSSProperties, FC } from 'react';
export interface ItemProps {
index?: number;
style?: CSSProperties;
}
const carouselItem: FC<ItemProps> = (props) => {
const { children, style } = props;
return (
<div className="g-carousel-item" style={style}>
{children}
</div>
);
};
export default carouselItem;
不明白为什么不仅没有动画效果而且CSSTransition的className也不存在,好像react-transition-group没有生效谢谢
我认为我们不需要使用 TransitionGroup
组件。 CSSTransition
本身支持一个in
属性,我们可以使用这个属性来控制它的可见性。
所以首先,将 in
条件添加到 CSSTransition
:
<CSSTransition
in={curIndex === index}
classNames="item"
timeout={300}
key={index}
>
然后,只需删除 TransitionGroup
:
<div className="g-carousel-wrapper">
<div className="g-carousel-window">
{React.Children.map(children, (child, index) => {
const childElement = child as FC<ItemProps>;
if (child.type !== CarouselItem) throw new Error('必须是Item');
return (
<CSSTransition
in={curIndex === index}
classNames="item"
timeout={300}
key={index}
>
{React.cloneElement(childElement, {
index,
style: { display: curIndex !== index && 'none' },
})}
</CSSTransition>
);
})}
</div>
</div>
它现在应该可以工作了:https://stackblitz.com/edit/react-ts-kqed2n?file=Carousel.tsx