[React] Redux store 생성하기(feat. magazine사이트만들기)

뷰 만들기 > redux store 만들기 > action, initialState 설정, reducer(+immer), export actionCreators > middleWare 연결

user.js
action, action creators, initialState, middleWare, reducer, export!

//redux store
import { createAction, handleActions } from "redux-actions";
import { produce } from "immer";
import { setCookie, getCookie, deleteCookie } from "../../shared/Cookie";

//Action
const LOG_IN = "LOG_IN";
const LOG_OUT = "LOG_OUT";
const GET_USER = "GET_USER";

const initialState = {
    user: null,
    is_login: false,
}

//middleWare actions
const loginAction = (user) => { 
    return function (dispatch, getState, {history}){
        console.log(history);
        dispatch(logIn()); 
        history.push("/"); // 로그인하면서 메인페이지로 이동
    }
}

//Action function
const logIn = createAction(LOG_IN, (user) => ({user}));
const logOut = createAction(LOG_OUT, (user) => ({user}));
const getUser = createAction(GET_USER, (user) => ({user}));

//Reducer
export default handleActions({
    [LOG_IN]:(state, action) => produce(state, (draft)=>{  //state : 원본 나의 정보. draft : immer가 원본 데이터를 복사한 것
        setCookie("is_login", "success");
        
        draft.user = action.payload.user;  //createAction을 사용하면 정보를 payload로 받아오기 때문에 action.payload.user로 빼줘야함
        //(payload: 넘겨준값)
        draft.is_login = true;
    }), 
  
    [LOG_OUT]: (state, action) => produce(state, (draft) => {
        deleteCookie("is_login");
        draft.user = null;
        draft.is_login = false;
    }),
  
    [GET_USER]:(state, action) => produce(state, (draft)=>{ }),
}, initialState);

const actionCreaters = {
    logIn,
    logOut,
    getUser,
    loginAction,
}
export { actionCreaters };

store 생성하기

  • combineReducers()를 사용해서 export한 reducer를 모아 root reducer를 생성
  • 미들웨어를 적용
  • createStore()를 사용해서 root reducer와 미들웨어를 엮어 스토어 생성
//store 생성하기
import {createStore, combineReducers, applyMiddleware, compose} from 'redux';
import thunk from 'redux-thunk';
import { createBrowserHistory } from "history";
import { connectRouter } from "connected-react-router";
import User from "./modules/user"; //해당 프로젝트 redux store

export const history = createBrowserHistory();

//스토어는 리듀서를 뭉친 걸 가지고 만듦
const rootReducer = combineReducers({
    user: User,
    router: connectRouter(history), //history와 router연결, store에 브라우저 히스토리 저장

});   //여러개의 reducer을 합칠 때에는 combineReducers({bucket1, bucket2 ,... })

//middleWares= [내가 사용할 미들웨어, .. ,]
const middleWares = [thunk.withExtraArgument({history:history})]; // withExtraArgument() : 추가적인 인자 같이 넘겨줌

//지금 어느 환경인지 알려줌(개발환경, 배포환경, ...)
const env = process.env.NODE_ENV;
if(env ==="development"){
    const {logger} = require("redux-logger"); // require쓰는 이유 ( 기능은 import와 비슷, import로 가져오면 모듈만 커짐, 개발할 때만 필요한 기능이라서 if문 돌릴 때만 잠깐 가져와서 사용하기 위해서)
    middleWares.push(logger);
}

//redux DevTool
const composeEnhancers =
  typeof window === "object" && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ // 현재 window환경이고, 거기에 __REDUX_DEVTOOLS_EXTENSION_COMPOSE__가 설치되어 서 사용하는건지
    ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
        // Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
      })
    : compose; //compose:조합

const enhancer = composeEnhancers(applyMiddleware(...middleWares));

const store = (initialStore) => (createStore(rootReducer, enhancer)); // middleWare의 모음집인 enhancer과 rootReducer 합쳐서 store 생성

export default store();

Redux DevTool:

리덕스 개발자 도구를 사용하면 현재 스토어의 상태를 개발자 도구에서 조회할 수 있음
지금까지 어떤 액션들이 디스패치 되었는지, 액션에 따라 상태가 어떻게 변화했는지 확인 가능
직접 액션 디스패치 가능

참고 - DevTool

좋은 웹페이지 즐겨찾기