์๋ ๋ฆฌ๋์ค๋ฅผ ๋ฅ์คํธ์์ ์ฌ์ฉํ๋ ๊ฒ์ ์๋นํ ๋ณต์กํฉ๋๋ค.
next-redux-wrapper๋ฅผ ์ฌ์ฉํ๋ฉด ๋น๊ต์ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ค์นํด์ค์๋ค.
yarn add next-redux-wrapper
๊ทธ๋ฆฌ๊ณ ๋ฃจํธ ๋๋ ํ ๋ฆฌ ์์ storeํด๋๋ฅผ ๋ง๋ ๋ค configureStore.jsํ์ผ์ ์์ฑํด์ฃผ์ธ์
๋ฒ์ ์ 6๋ฒ์ ์
๋๋ค.
๊ธฐ๋ณธ์ ์ธ ํ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
import { createWrapper } from "next-redux-wrapper";
const configureStore = () => {};
const wrapper = createWrapper(configureStore);
export default wrapper;
๋ค์์ ๋ฆฌ๋์ค์ ๋ํ ์์ธํ ๋ด์ฉ์ ๋ณผ ์ ์๋๋ก wrapper์์ ์ต์
์ ์ฃผ๊ฒ ์ต๋๋ค.
const wrapper = createWrapper(configureStore, {
debug: process.env.NODE_ENV === "development",
});
๋ค์์ _app.js๋ก ์ด๋ํด์ ์ ์ผ ์์ ์ปจํ
์ด๋๋ฅผ ๋ฆฌ๋์ค๋ก ๊ฐ์ธ์ฃผ๊ฒ ์ต๋๋ค.
import React from "react";
import Head from "next/head";
import "antd/dist/antd.css";
import wrapper from "../store/configureStore";
function _app({ Component }) {
return (
<div>
<Head>
<meta charSet="utf-8"></meta>
<title>Wongeun</title>
</Head>
<Component />
</div>
);
}
//๊ฐ์ธ์ค๋ค.
export default wrapper.withRedux(_app);
์ฌ๋ฌ ์ปดํฌ๋ํธ์์ ๊ณตํต์ ์ผ๋ก ์ฐ์ด๋ ๋ฐ์ดํฐ๊ฐ ์๋๋ฐ,
์ปดํฌ๋ํธ๋ ๋ถ๋ฆฌ๊ฐ ๋์ด์๊ธฐ ๋๋ฌธ์ ๊ทธ ๋ฐ์ดํฐ๋ค์ ๋ถ๋ชจ์ปดํฌ๋ํธ์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ์์์ผ๋ก ์ค์ผ ํฉ๋๋ค.
redux๋ ์ค์์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ ์ปดํฌ๋ํธ๊ฐ ํ์๋ก ํ ๋ ๊ทธ ๋ฐ์ดํฐ๋ฅผ ๋ฟ๋ ค์ฃผ๋๋ฐ,
react์ ContextAPI, Redux , graphQL , MobX ๋ฑ์ด ์์ต๋๋ค.
๊ฐ๊ฐ์ ์ฅ๋จ์ ์ด ์๋๋ฐ
Redux๋ ์ฑ์ด ์์ ์ ์ด์ง๋ง, ์ฝ๋๋์ด ๋ง์ต๋๋ค.
MobX๋ ์ฝ๋๋์ ์ ์ง๋ง, ๋์ด๋๊ฐ ์๊ตฌ๋์ฃ ..
๊ฐ๋จํ ์์
์ ContextAPI๋ฅผ ์ด์ฉํ๋ฉด ๋๋๋ฐ,
ContextAPI๋ฅผ ์ด์ฉํ๋ฉด ๋น๋๊ธฐ ์์
์ ์ฒ๋ฆฌํ๊ธฐ์ ์์ด์ ์ด๋ ต๊ธฐ ๋๋ฌธ์
์ด๋ฒ์๋ Redux๋ฅผ ์ฌ์ฉํด๋ณด๊ฒ ์ต๋๋ค.
์ ์ฉ๋ฒ
Next์์๋ ์ฐ๋ฆฌ๊ฐ ์๋ ๋ฆฌ๋์ค์ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ํตํด ์ ์ฉ์ํต๋๋ค.
storeํด๋๋ฅผ ์์ฑํ๋ค configureStoreํ์ผ์ ๋ง๋ค๊ณ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํด์ฃผ์ธ์
import { createWrapper } from "next-redux-wrapper";
import { createStore } from "redux";
import reducer from "../reducers";
const configureStore = () => {
const store = createStore(reducer);
return store;
};
const wrapper = createWrapper(configureStore, {
debug: process.env.NODE_ENV === "development",
});
export default wrapper;
๊ทธ๋ฆฌ๊ณ app.js ํ์ผ์ ๋ค์ด๊ฐ์_app ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ธ์ค๋๋ค.
import React from "react";
import Head from "next/head";
import "antd/dist/antd.css";
import wrapper from "../store/configureStore";
function _app({ Component }) {
return (
<div>
<Head>
<meta charSet="utf-8"></meta>
<title>Wongeun</title>
</Head>
<Component />
</div>
);
}
//๊ฐ์ธ์ค๋ค.
export default wrapper.withRedux(_app);
๋ฆฌ๋์ค ์ ์ฉ์ด ์๋ฃ๋์์ต๋๋ค.
๋ฆฌ๋์ค์ ์ก์
ํจ์์ ๋ฆฌ๋์๋ฅผ ๋ง๋ค์ด ๋ณผ๊น์?
const LOG_IN = "users/LOG_IN";
const LOG_OUT = "users/LOG_OUT";
export const logIn = () => ({ type: LOG_IN });
export const logOut = () => ({ type: LOG_OUT });
const initialState = {
user: {
isloggedIn: false,
user: null,
signUpData: {},
loginData: {},
},
post: {
mainPosts: [],
},
};
export default function users(state = initialState, action) {
switch (action.type) {
case LOG_IN:
return { ...state, user: { ...state.user, isloggedIn: true } };
case LOG_OUT:
return { ...state, user: { ...state.user, isloggedIn: false } };
default:
return state;
}
}
๊ฐ๋ฐ์ ๋๊ตฌ
yarn add redux-devtools-extension
๊ฐ๋ฐ์ ๋๊ตฌ๋ฅผ ๋ค์ด๋ฐ์ ๋ค ์คํ ์ด์ ์ ์ฉํด์ฃผ๋ฉด ๋ฉ๋๋ค.
import { createWrapper } from "next-redux-wrapper";
import { createStore, applyMiddleware, compose } from "redux";
import reducer from "../reducers";
import { composeWithDevTools } from "redux-devtools-extension";
const configureStore = () => {
const middlewares = [];
const enhancer =
process.env.NODE_ENV === "production"
? compose(applyMiddleware(...middlewares)) //๋ฐฐํฌ์ฉ
: composeWithDevTools(applyMiddleware(...middlewares)); //๊ฐ๋ฐ์ฉ
const store = createStore(reducer, enhancer);
return store;
};
const wrapper = createWrapper(configureStore, {
debug: process.env.NODE_ENV === "development",
});
export default wrapper;
๋ฏธ๋ค์จ์ด๋ ๋์ค์ ์ ์ฉ์ํค๊ธฐ ์ํ ๊ณต๊ฐ์ ๋ง๋ค์ด ๋ ๊ฒ์
๋๋ค.
๊ผญ ๋ฆฌ๋์์์ ๋ถ๋ณ์ฑ์ ์ง์ผ์ค์ผ๋ง ํ์คํ ๋ฆฌ๊ฐ ์ ์ง๋์ด ๋์ํ ์์๋๊ฒ์
๋๋ค.
๋ฆฌ๋์๋ถํด
import { HYDRATE } from "next-redux-wrapper";
import user from "./user";
import post from "./post";
import { combineReducers } from "redux";
const rootReducer = combineReducers({
// HYDRATE SSR์ ์ํด ์ผ๋ถ๋ฌ ๋ง๋ค์ด ์ง ๊ฒ์
๋๋ค.
index: (state = {}, action) => {
switch (action.type) {
case HYDRATE:
return { ...state, ...action.payload };
default:
return state;
}
},
user,
post,
});
export default rootReducer;
const LOG_IN = "users/LOG_IN";
const LOG_OUT = "users/LOG_OUT";
export const logIn = () => ({ type: LOG_IN });
export const logOut = () => ({ type: LOG_OUT });
export const initialState = {
isloggedIn: false,
user: null,
signUpData: {},
loginData: {},
};
export default function reducer(state = initialState, action) {
switch (action.type) {
case LOG_IN:
return { ...state, isloggedIn: true };
case LOG_OUT:
return { ...state, isloggedIn: false };
default:
return state;
}
}
export const initialState = {
mainPosts: [],
};
export default function reducer(state = initialState, action) {
switch (action.type) {
default:
return state;
}
}
์ปดํฌ๋ํธ๋ฅผ ๊ตฌ์ฑํ๊ธฐ ์ ์postReducer๋ ๊ตฌ์ฑํด๋ณผ๊ฒ์
export const initialState = {
mainPosts: [
{
id: 1,
User: {
id: 1,
nickname: "์ ๋ก์ด",
},
content: "์ฒซ๋ฒ์งธ๊ฒ์๊ธ",
Images: [
{
src:
"https://media.vlpt.us/images/wooder2050/post/d2764478-dc72-4cc9-9128-f66bfb8b3aa3/reactintroduction.png",
},
{
src:
"https://media.vlpt.us/images/wooder2050/post/d2764478-dc72-4cc9-9128-f66bfb8b3aa3/reactintroduction.png",
},
{
src:
"https://media.vlpt.us/images/wooder2050/post/d2764478-dc72-4cc9-9128-f66bfb8b3aa3/reactintroduction.png",
},
],
Comments: [
{
User: {
nickname: "nero",
},
content: "์์ฐ",
},
{
User: {
nickname: "hero",
},
content: "์ค์์์",
},
],
},
],
imagePaths: [],
postAdded: false,
};
//์ก์
์์ฑ
const ADD_POST = "ADD_POST";
export const addPost = () => ({
type: ADD_POST,
});
//๊ฐ์ง๋ฐ์ดํฐ
const dummyPost = {
id: 2,
content: "๋๋ฏธ์
๋๋ค",
User: {
id: 1,
nickname: "conrad",
},
Images: [],
Comments: [],
};
export default function reducer(state = initialState, action) {
switch (action.type) {
case ADD_POST:
return {
...state,
mainPosts: [dummyPost, ...state.mainPosts], //์์ ์ถ๊ฐํด์ผ ๊ฒ์๊ธ์ด ์์ ๋ํ๋๋ค.
postAdded: true,
};
default:
return state;
}
}
๋๋ฏธ๋ฐ์ดํฐ๋ฅผ ํ์ฉํ์์ต๋๋ค.
์ฒ์์ FE ๊ฐ๋ฐ์๋ BE๊ฐ๋ฐ์์ ์ ๋
ผ์ํ์ฌ์ ๋๋ฏธ๋ฐ์ดํฐ๋ฅผ ์ ๋ง๋ค์ด ๋๋๊ฒ์ด ์ค์ํฉ๋๋ค.
๋ํ ๊ทธ ๋๋ฏธ๋ฐ์ดํฐ๋ ์กฐ๊ธ์ ๋ฐ๋์๋ ์๋ค๋๊ฑธ ์๊ณ ์์ด์ผ ํฉ๋๋ค.