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

- Author: @devkonis
- Published: 2023-08-24
- Updated: 2023-08-24
- Source: http://blex.me/@devkonis/react-%EC%95%A0%EB%8B%88%EB%A9%94%EC%9D%B4%EC%85%98-%ED%99%9C%EC%9A%A9%EC%8B%9C-%EB%B9%84%EB%8F%99%EA%B8%B0-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%AC%B8%EC%A0%9C%EC%A0%90
- Tags: 비동기, react, 클론코딩, swiper, disneyplus, pagination

---

## 문제
---
disneyPlusApp을 clone코딩하다가 swiper의 pagination이 동작하지 않는 문제 발생

#### 예상되는 원인
---
영화 데이터를 불러올때 async를 사용하여 비동기로 처리하였는데, swiper는 동기방식으로 데이터가 들어오기전에 애니메이션이 활성화 되어 제대로 동작하지 않음

#### why?
--- 
1. 애니메이션을 처리하는 과정에서 오류가 발생했을때 오히려 pagination 애니메이션이 정상적으로 작동함(?)
1. 중간에 실시간으로 변환할 경우 데이터가 이미 불러져 있는 경우 pagination이 잘 작동하였음

#### 해결방안
---
비동기데이터가 로드된 이후에 애니메이션 처리를 할 수 있게 변경함
```javascript
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<br>
- [Github Link](https://github.com/DevKonis/React-Disney-Plus-Clone)<br>
- [Live Link](https://react-disneyplusapp.web.app)
