잼무비

Part 5. Redux-toolkit으로 리팩토링하기

잼굴 2022. 11. 30. 12:25

공포의 리덕스

 

리덕스 툴킷을 사용하면 리덕스를 좀 더 간편하게 사용할수있다고해서 기존에 리덕스로 작성한것을 리덕스 툴킷으로 리팩토링 하였다.

 

 

1. 리덕스 툴킷 설치

npm install @reduxjs/toolkit react-redux

 


 

2. Reducer 바꾸기

 

일단 툴킷-리듀서의 핵심 createSlice를 import한다

import {createSlice} from "@reduxjs/toolkit"

 

createSlice를 사용하면 직점 action name을 설정할 필요가없다. 알아서 해준다.

 

const ~~~ = createSlice({

name: ~~

initialState,

reducers: { ~~ }

})

기본적인 양식 저 reducers: { } 안에 기존에 switch 안에 return에 적었던 내용들을 옮겨준다.

 

1) 툴킷버전에서 기존의 case는 함수형태로 작성해준다. 매개변수는 2개를 가지는데, state와 action이다

2-1) 일단 return 할 필요가 없고, ...state를 적어줘야 하는일도 없다. 안적어도 알아서 해준다.

2-2) state에 있는 popularMovies의 값을 payload의 데이터로 바꿔준다. payload는 action에서 오기때문에 action.payload.~~~를 해준다

3) createSlice가 반환하는 내용을  movieSlice에 저장을한다.

4) export 해준다.

function movieReducer(state=initialState,action){
let{type,payload} = action
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}
}
}

이것이 기존 리덕스 사용시 리듀서 코드였는데

 

 const movieSlice = createSlice({
    name: 'movie',
    initialState,
    reducers: {
        getMovieRequest(state,action){
            state.loading = action.true
        },
        getMovieSuccess(state,action){
            state.popularMovies = action.payload.popularMovies;
            state.topRatedMovies = action.payload.topRatedMovies;
            state.upcomingMovies = action.payload.upcomingMovies;
            state.genreList = action.payload.genreList;
            state.loading = action.false
        },
        getMoviesFail(state,action){
            state.loading = action.false
        }
    }
});

export default movieSlice.reducer;

툴킷 양식의 리듀서 코드는 간결해졌다. 

 


 

3. Store 바꾸기

 

리덕스는 더이상 createStore를 지원을 안한다! 

그래서 줄그어져있다

이제 사용하는것은 configureStore

 

기존에 createStore을 할때 rootReducer를  index.js에서 combineReducer를 통해서 합친 reducer를 store로 전달하였다.

 

configureStore를 사용함으로써 항상 사용해야했던 combinereducer, thunk, applyMiddleware, composeWithDevTools 작업을 안해줘도 된다. 왜냐면 자동으로 다 들어가있기 때문 !!

 

reducer를 들고 오기위해서 reducer를 import 해준다. 그리고 store에 넣어준다.

import movieReducer from './reducers/movieReducer';
import { configureStore } from "@reduxjs/toolkit";

const store = configureStore({
    reducer:{
        movie : movieReducer,
    }
})

export default store;

Store는 이게 다다.. index.js 파일 삭제 완료...

 


4. Action 바꾸기

 

기존에는 dispatch 하기 위해서 

           dispatch({
            type: "GET_MOVIES_SUCCESS",
            payload: {popularMovies:popularMovies.data, 
                topRatedMovies: topRatedMovies.data,
                 upcomingMovies: upcomingMovies.data,
                 genreList: genreList.data.genres,
                 loading: false,
                }

이런 형식으로 작성하였다.

 

툴킷에서는 바로 Object를 던져주는것이 아니라 createSlice가 만든 Action값을 들고와야한다.

그래서 일단 reducer에서 export해온다. 무엇을? 아까만든 productSlice의 Action값을

 

export const movieAction = movieSlice.actions;

리듀서에서 export 해준다.

import { movieAction } from "../reducers/movieReducer";

Action에서 import 해주고

 

      dispatch(
        movieAction.getMovieSuccess({
          popularMovies: popularMovies.data,
          topRatedMovies: topRatedMovies.data,
          upcomingMovies: upcomingMovies.data,
          genreList: genreList.data.genres,
          loading: false,
        })
      );

이런식으로 함수를 호출해서 dispatch 하면된다.

더이상 action 객체를 만들어 줄 필요없이 그냥 action 함수를 호출한다.

 

payload 값은 어떻게 넘기지? 그냥 간단하게 매개변수로 전달해주면 된다.

매개변수로 전달된 값은 알아서 payload 필드 아래로 들어간다.

 

 

바꾸면서 헤맨점:

 

dispatch에서 payload값을 어떻게 넘기는지 헷갈렸다. 처음엔 

 

dispatch(
movieAction.getMovieSuccess({popularMovies,topRatedMovies,upcomingMovies,genreList})
);

이런식으로만 적었는데 

매개변수로 PopularMovies : popularMovies.data 이렇게 하나하나 적어줘야했다.