[REACT] 애니메이션 활용시 비동기 데이터 문제점

[REACT] 애니메이션 활용시 비동기 데이터 문제점

문제


disneyPlusApp을 clone코딩하다가 swiper의 pagination이 동작하지 않는 문제 발생

예상되는 원인


영화 데이터를 불러올때 async를 사용하여 비동기로 처리하였는데, swiper는 동기방식으로 데이터가 들어오기전에 애니메이션이 활성화 되어 제대로 동작하지 않음

why?


  1. 애니메이션을 처리하는 과정에서 오류가 발생했을때 오히려 pagination 애니메이션이 정상적으로 작동함(?)
  2. 중간에 실시간으로 변환할 경우 데이터가 이미 불러져 있는 경우 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

이 글이 도움이 되었나요?

신고하기
0분 전
작성된 댓글이 없습니다. 첫 댓글을 달아보세요!
    댓글을 작성하려면 로그인이 필요합니다.