Next에서도 전연 상태관리 Redux를 사용해 봅시다😎
이 포스팅은 제로초님의 노드버드 강의를 듣고 정리한 내용입니다.
Next.js에서 redux
를 사용하는 방법이 퓨어 react와 좀 다릅니다.
redux
와 next-redux-wrapper
를 npm을 통해 설치해줍니다.(next-redux-wrapper 버전 6 기준)
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;
page
폴더 -> _app.js
파일 Component를 withRedux
로 감싸줌// _app.js
import wrapper from '../store/configureStore';
...
// export 부분
export default wrapper.withRedux(App);
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들을 만들어 줄수 있습니다.
위의 예제에 나타난 user
와 post
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;