'Question about the animation effect of the React carousel component
I wrote a carousel component with react and react-transition-group, but the animation of the carousel is not working properly. When the image changes from 0 to 1, the 0 will disappear immediately, instead of waiting for the animation to end and then disappear.
The Code Link is as follow
https://stackblitz.com/edit/react-ts-eawtuk?file=CarouselItem.tsx
The core codes are as follow
Carousel Component
import React, {
FC,
Fragment,
ReactNode,
useMemo,
useState,
} from 'react';
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);
};
setTimeout(onNext, 3000);
return (
<Fragment>
<button onClick={onPrev}>prev</button>
<button onClick={onNext}>next</button>
<div className="g-carousel">
<div className="g-carousel-window">
<div className="g-carousel-wrapper">
{React.Children.map(children, (child, index) => {
const ChildElement = child as FC<ItemProps>;
if (child.type !== CarouselItem) throw new Error('必须是Item');
return React.cloneElement(ChildElement, { index, curIndex });
})}
</div>
</div>
</div>
</Fragment>
);
};
type CarouselType = {
Item: FC<ItemProps>;
} & FC<Props>;
const Carousel: CarouselType = Component as CarouselType;
Carousel.Item = CarouselItem;
export default Carousel;
CarouselItem Component
import React, { CSSProperties, FC, Fragment, useMemo } from 'react';
import { CSSTransition } from 'react-transition-group';
export interface ItemProps {
curIndex?: number;
index?: number;
style?: CSSProperties;
}
const carouselItem: FC<ItemProps> = (props) => {
const { children, index, curIndex } = props;
const visible = useMemo(() => curIndex === index, [curIndex]);
return (
<Fragment>
<CSSTransition
in={visible}
classNames="carousel"
timeout={500}
key={index}
>
<div
className="g-carousel-item"
style={{ display: curIndex !== index && 'none' }}
>
{children}
</div>
</CSSTransition>
</Fragment>
);
};
export default carouselItem;
And css
.g-carousel {
&-window {
overflow: hidden;
}
&-wrapper {
position: relative;
}
}
.carousel-exit {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.carousel-enter,
.carousel-exit {
transition: all 0.5s;
}
.carousel-enter-active {
transform: translateX(-100%);
}
.carousel-enter.reverse {
transform: translateX(100%);
}
.carousel-exit-done {
transform: translateX(100%);
}
.carousel-exit-done.reverse {
transform: translateX(-100%);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
