React로 NodeBird SNS 만들기 3 리덕스 적용하기

재 밌 다!

재밌어서 색상을 바꾸고 강조해보았다(div태그 이용).
오랜만에 리액트를 만지니까 재밌다.
오늘은 프로젝트에 리덕스를 적용하였다.
next에는 redux를 적용할 수 있도록 도와주는 고마운 라이브러리가 있다.
또한 기존의 redux와 달리 라이브러리에서 자동으로 provider로 감싸주기 때문에 provider로 감싸지 않아도 된다.

설치하기

라이브러리들을 설치해준다.

1
2
3
npm i next-redux-wrapper로 설치
npm i redux
npm i react-redux

리듀서 작성하기

먼저 루트 디렉터리에 reducer 폴더를 만든다.

위 reducer 폴더에 user.js파일을 만들고 개요를 작성해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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,
user: action.data,
isLoggedIn: true,
};
}
case "LOG_OUT": {
return {
...state,
user: null,
isLoggedIn: false,
};
}
default:
return state;
}
};

export default reducer;

마찬가지로 reducer 폴더에 post.js파일을 만들고 개요를 작성해준다.

1
2
3
4
5
6
7
8
9
10
11
12
export const initialState = {
mainPosts: [],
};

const reducer = (state = initialState, action) => {
switch (action.type) {
default:
return state;
}
};

export default reducer;

마지막으로 해당 경로에 index.js파일을 만들고
리듀서들을 합쳐준다.
HYDRATE는 서버사이드 랜더링을 위한 것이라고 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { HYDRATE } from "next-redux-wrapper";
import user from "./user";
import post from "./post";
import { combineReducers } from "redux";
const initialState = {};

const rootReducer = combineReducer({
index: (state = {}, action) => {
switch (action.type) {
case HYDRATE:
return { ...state, ...action.payload };
default: {
return state;
}
}
},
user,
post,
});
export default rootReducer;

스토어 만들기

루트 디렉토리에 store폴더를 만들고 configureStore.js 파일을 작성해준다.
redux devtools또한 적용하였다.
개발모드일 때랑 배포모드일 때 미들웨어를 다르게 하였다.
마지막으로 래퍼를 생성해 반환한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { createWrapper } from "next-redux-wrapper";
import { applyMiddleware, compose, createStore } 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;

적용하기

가장 상위 파일인 app.js를 다음과 같이 감싸준다.
그러면 라이브러리에서 provider로 자동으로 감싸준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import PropTypes from "prop-types";
import "antd/dist/antd.css";
import Head from "next/head";
import wrapper from "../store/configureStore";

const App = ({ Component }) => {
return (
<>
<Head>
<title>NodeBird</title>
<meta charSet="utf-8" />
</Head>
<Component />
</>
);
};

App.propTypes = {
Component: PropTypes.elementType.isRequired,
};

export default wrapper.withRedux(App);

사용하기

기존 redux와 동일하게 useSelector, useDispatch를 사용할 수 있다.

댓글