잼무비

Part4 로딩 스피너 제작하기

잼굴 2022. 11. 28. 15:54

데이터를 불러오는동안 로딩스피너를 보여주고자 한다

 

https://www.npmjs.com/package/react-spinners

 

react-spinners

A collection of react loading spinners. Latest version: 0.13.6, last published: 2 months ago. Start using react-spinners in your project by running `npm i react-spinners`. There are 711 other projects in the npm registry using react-spinners.

www.npmjs.com

 

우선 이곳에서 제공해주는 npm을 이용하기위해  react-spinners를 다운 받는다.

 

사용법

대략적인 사용방법이 적혀있다. 하지만 리액트에서 제대로 사용하기위해서는 저거뿐만 아니라 리덕스에서 각종 설정들을 해줘야한다. 

 

스피너는 Home에서 useEffect로 영화가 도착하기전에 보여주기위해 Home에서 사용할것이다.

  if (loading) {
    return <ClipLoader color="red" loading={loading} size={150} />;
  }

loading이라는 값이 true일때만 나타나게 하기위해 if문을 사용하였다. true이면 나타나고, false라면 사라지고

 

true와 false는 어떻게 구분할까?

데이터 도착 전 = true  스피너 보여주기

데이터 도착 후, 에러가 났다면 = false  스피어 안보여주기

 

데이터 도착 전후를 알수있는곳은 어디일까?  redux의 Action !!

 

API 요청 하기 전 = 데이터 도착 전

API 요청 후 = 데이터 도착 후

 

그러기 위해 Reducer의 initialState에 loading을 추가한다

let initialState = {
    popularMovies:{},
    topRatedMovies:{},
    upcomingMovies:{},
    loading: true,
};

 

function getMovies(){
    return async (dispatch)=>{
        try{
            dispatch({type:"GET_MOVIES_REQUEST"})
            const popularMovieApi = api.get(`movie/popular?api_key=${API_KEY}&language=en-US&page=1`)
            const topRateApi = api.get(`movie/top_rated?api_key=${API_KEY}&language=en-US&page=1`)
            const upComingApi = api.get(`movie/upcoming?api_key=${API_KEY}&language=en-US&page=1`)
            const genreApi = api.get(`/genre/movie/list?api_key=${API_KEY}&language=en-US`)
           let [popularMovies, topRatedMovies, upcomingMovies,genreList ] = await Promise.all([popularMovieApi,topRateApi,upComingApi,genreApi])
           dispatch({
            type: "GET_MOVIES_SUCCESS",
            payload: {popularMovies:popularMovies.data, 
                topRatedMovies: topRatedMovies.data,
                 upcomingMovies: upcomingMovies.data,
                 genreList: genreList.data.genres,
                 loading: false,

                },
           })
        } catch(error){
            dispatch({type: "GET_MOVIES_FAIL"})
        }
}}

에러 핸들링을 위해서 try catch문을 사용한다.

API호출전에 로딩을 시작시키기 위해 GET_MOVIES_REQUEST를 통해서 로딩을 TRUE로 바꾼다.

쭈루룩 API호출이 다 됐다면 GET_MOVIES_SUCCESS를 통해서 로딩을 FALSE로 바꾼다.

에러가 발생하면 GET_MOVIES_FAIL로 로딩을 FALSE로 바꿔준다.

 

switch(type){
    case "GET_MOVIES_REQUEST":
        return {...state, loading:true}
    case "GET_MOVIES_SUCCESS":
        return {...state,popularMovies: payload.popularMovies, 
            topRatedMovies: payload.topRatedMovies, 
            upcomingMovies: payload.upcomingMovies,
            genreList:payload.genreList,
            loading: false,
        };
    case "GET_MOVIES_FAIL":
        return{...state,loading: false}
default: return{...state}
}

switch에서 GET_MOVIES_REQUEST를 받아주고, TRUE로 바꿔준다.  GET_MOVIES_SUCCESS로 FALSE로 바꿔준다.

GET_MOVIES_FAIL로 FALSE로 바꿔준다.

 

마지막으로 만든것을 이용하기위해 HOME의 useSelector에 loading을 추가해준다.

 const { popularMovies, topRatedMovies, upcomingMovies, loading } =
    useSelector((state) => state.movie);

 

 

잘된다