Next에서 Redux 사용하기

김예찬·2021년 6월 9일
0

Next에서도 전연 상태관리 Redux를 사용해 봅시다😎

이 포스팅은 제로초님의 노드버드 강의를 듣고 정리한 내용입니다.

Next.js에서 redux를 사용하는 방법이 퓨어 react와 좀 다릅니다.

디펜던시

reduxnext-redux-wrapper를 npm을 통해 설치해줍니다.(next-redux-wrapper 버전 6 기준)


사용 방법

  1. front 서버에 stor 폴더 -> configureStore.js 파일 생성
// configureStore.js 내용

import { createWrapper } from 'next-redux-wrapper';
import { applyMiddleware, compose, createStore } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import rootReducer from '../reducers';


const configureStore = () => {
    const middlewares = [];
    const enhancer = process.env.NODE_ENV === 'production'
        ? compose(applyMiddleware(...middlewares))
        : composeWithDevTools(compose(applyMiddleware(...middlewares)));
    const store = createStore(rootReducer, enhancer);
    return store;
};

const wrapper = createWrapper(configureStore, { 
    debug: process.env.NODE_ENV === 'development',
});

export default wrapper;

  1. page 폴더 -> _app.js 파일 Component를 withRedux로 감싸줌
// _app.js

import wrapper from '../store/configureStore';

...

// export 부분
export default wrapper.withRedux(App);
  1. reducers 폴더 -> index.js
import { HYDRATE } from 'next-redux-wrapper';
import { combineReducers } from 'redux';
import user from './user';
import post from './post';


// ssr을 위한 reducer;
const reducer = (state = {} , action) => {
    switch(action.type) {
        case HYDRATE:
            return {
                ...state,
                ...action.payload,
            }
        default:
            return state;
    }
}

const rootReducer = combineReducers({
    index : reducer,
    user,
    post,
})

export default rootReducer;

reducers의 폴더엔 또 다른 reducer들을 만들어 줄수 있습니다.
위의 예제에 나타난 userpost js파일 또한 reducers 폴더 안에 만들어 줍니다.

// 예시로 post.js 파일만 만들어 보겠습니다.

// 액션 타입 정의
const ADD_POST = 'post/ADD_POST';

// 액션 생성 함수
export const addPost = () => ({
    type: ADD_POST,
})

// dummy
const dummyPost = {
    id: 2,
    content: '더미데이터입니다.',
    User: {
        id: 1,
        nickname: "와빵"
    },
    Images: [],
    Comments: [],
};

// 이니셜 스테이트
const initialState = {
    mainPosts: [{
        id: 1,
        content: '첫 번째 게시글 #해시 태그 #익스프레스',
        User: {
            id: 1,
            nickname: "와빵",
        },
        Images: [
            {
                src: 'https://bookthumb-phinf.pstatic.net/cover/137/995/13799585.jpg?update=20180726',
            },
            {
                src: 'https://gimg.gilbut.co.kr/book/BN001958/rn_view_BN001958.jpg',
            },
            {
                src: 'https://gimg/gilbut.co.kr/book/BN001998/rn_view_BN001998.jpg',
            },
        ],
        Comments: [
            {
                User: {
                    nickanme: 'nero',
                },
                content: '우왕 신기하다~'  
            },
            {
                User: {
                    nickname: 'yolo',
                },
                content: 'ㅎㅎ 오래된 책 같은데여?'
            }
        ]
    }],
    imagePaths: [],
    postAdded: false,

};


// 리듀서
const post = ( state = initialState, action ) => {
    switch (action.type) {
        case ADD_POST:
            return {
                ...state,
                mainPosts: [dummyPost, ...state.mainPosts],
                postAdded: true,
            }
        default:
            return state;
    }
}
export default post;
profile
프론트엔드

0개의 댓글