npm i next-redux-wrapper@6 react-redux redux redux-devtools-extension
store/configureStore.js 파일 만들기
import { createWrapper } from "next-redux-wrapper";
import { applyMiddleware, compose, createStore } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import reducer from "../reducers/index";
const configureStore = () => {
const middlewares = [];
//개발모드일때는 redux-devtools-extension사용가능하게
const enhancer =
process.env.NODE_ENV === "production"
? compose(applyMiddleware(...middlewares))
: composeWithDevTools(applyMiddleware(...middlewares));
const store = createStore(reducer, enhancer); //앱의 상태를 유지하는 Redux 스토어를 만듭니다
return store;
};
const wrapper = createWrapper(configureStore, {
debug: process.env.NODE_ENV === "development",
});
export default wrapper;
reducers/index.js
import { HYDRATE } from "next-redux-wrapper";
const initialState = {
user: {
isLoggedIn: false,
user: null,
signUpdata: {},
loginData: {},
},
post: {
mainPosts: [],
},
};
export const loginAction = data => {
return {
type: "LOG_IN",
data,
};
};
export const logoutAction = () => {
return {
type: "LOG_OUT",
};
};
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case HYDRATE:
return {
...state,
...action.payload,
};
case "LOG_IN":
return {
...state,
user: {
...state.user,
isLoggedIn: true,
user: action.data,
},
};
case "LOG_OUT":
return {
...state,
user: {
...state.user,
isLoggedIn: false,
user: null,
},
};
default:
return state;
}
};
export default rootReducer;
적용
import PropTypes from "prop-types";
import Head from "next/head";
import "antd/dist/antd.css";
import wrapper from "../store/configureStore";
const App = ({ Component }) => {
// pages의 공통 부분
return (
<>
<Head>
<meta charSet="utf-8" />
<title>NodeBird</title>
</Head>
<Component />
</>
);
};
App.propTypes = {
Component: PropTypes.elementType.isRequired,
};
export default wrapper.withRedux(App);
Reducer쪼개기
user Reducer 만들기
reducers/user.js
export const initialState = {
isLoggedIn: false,
user: null,
signUpdata: {},
loginData: {},
};
export const loginAction = data => {
return {
type: "LOG_IN",
data,
};
};
export const logoutAction = () => {
return {
type: "LOG_OUT",
};
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case "LOG_IN":
return {
...state,
isLoggedIn: true,
user: action.data,
};
case "LOG_OUT":
return {
...state,
isLoggedIn: false,
user: null,
};
default:
return state;
}
};
export default reducer;
post Reducer 만들기
reducers/post.js
export const initialState = {
mainPosts: [],
};
const reducer = (state = initialState, action) => {
switch (action.type) {
default:
return state;
}
};
export default reducer;
우리는 현재 두가지의 리덕스 모듈을 만들었습니다. 그래서 리듀서도 두개죠. 한 프로젝트에 여러개의 리듀서가 있을때는 이를 한 리듀서로 합쳐서 사용합니다. 합쳐진 리듀서를 우리는 루트 리듀서라고 부릅니다.
reducers/index.js
리듀서를 합치는 작업은 리덕스에 내장되어있는 [combineReducers](https://redux.js.org/api/combinereducers)
라는 함수를 사용합니다.
import { HYDRATE } from "next-redux-wrapper";
import { combineReducers } from "redux";
import user from "./user";
import post from "./post";
const rootReducer = combineReducers({
index: (state = {}, action) => { //ssr을위해 index리듀서가 들어간다.
switch (action.type) {
case HYDRATE:
return {
...state,
...action.payload,
};
default:
return state;
}
},
user,
post,
});
export default rootReducer;