문제
disneyPlusApp을 clone코딩하다가 swiper의 pagination이 동작하지 않는 문제 발생
예상되는 원인
영화 데이터를 불러올때 async를 사용하여 비동기로 처리하였는데, swiper는 동기방식으로 데이터가 들어오기전에 애니메이션이 활성화 되어 제대로 동작하지 않음
why?
- 애니메이션을 처리하는 과정에서 오류가 발생했을때 오히려 pagination 애니메이션이 정상적으로 작동함(?)
- 중간에 실시간으로 변환할 경우 데이터가 이미 불러져 있는 경우 pagination이 잘 작동하였음
해결방안
비동기데이터가 로드된 이후에 애니메이션 처리를 할 수 있게 변경함
const Row = ({ title, id, fetchUrl }) => {
const [movies, setMovies] = useState([]);
const [isSuccess, setIsSuccess] = useState(false);
// 데이터 로드됐는지 확인할 state
const [modalOpen, setModalOpen] = useState(false);
const [movieSelected, setMovieSelected] = useState({});
const fetchMovieData = useCallback(async () => {
try {
// try catch 구문으로 데이터 불러오면 isSuccess를
// true로 변경해줌. 아니면 에러 발생되게함
const response = await axios.get(fetchUrl);
setMovies(response.data.results);
setIsSuccess(true);
} catch (error) {
console.log("Failed to fetch movie data: ", error)
}
}, [fetchUrl]);
useEffect(() => {
fetchMovieData();
}, [fetchMovieData]);
const handleClick = (movie) => {
setModalOpen(true);
setMovieSelected(movie);
};
return (
<Container>
<h2>{title}</h2>
{isSuccess && (
// 이부분에 isSuccess가 true일 경우(데이터가 로드될 경우)에
// 애니메이션 실행되게 묶어줌
<Swiper
modules={[Navigation, Pagination, Scrollbar, A11y]}
loop={true}
navigation
pagination={{ clickable: true }}
breakpoints={{
1378: {
slidesPerView: 6,
slidesPerGroup: 6,
},
998: {
slidesPerView: 5,
slidesPerGroup: 5,
},
625: {
slidesPerView: 4,
slidesPerGroup: 4,
},
0: {
slidesPerView: 3,
slidesPerGroup: 3,
},
}}
>
<Content id={id}>
{movies.map((movie) => (
<SwiperSlide key={movie.id}>
<Wrap>
<img
key={movie.id}
src={`https://image.tmdb.org/t/p/original${movie.backdrop_path}`}
alt={movie.name}
onClick={() => handleClick(movie)}
/>
</Wrap>
</SwiperSlide>
))}
</Content>
</Swiper>
)}
{modalOpen && (
<MovieModal {...movieSelected} setModalOpen={setModalOpen} />
)}
</Container>
);
};
결과
work well! :D
Ghost