우리가 코드를 짜면서 많은 것을 신경쓰고 유의해야 할 것이 있다. 그 중 하나가 가독성 높은 코드 유지보수가 좋은 코드이다.
Redux 구조 잡기
store가 있는 index에서 코드의 줄이 길어 질 수 있는 action과 reducer를 분리해보왔다.
초기코드
// src => index.js import { createStore } from "redux"; const reducer = (preveState = initialState, action) => { switch (action.type) { case "기본": return { ...preveState, client: action.data }; case "맵게": return { ...preveState, client: action.data }; case "로제": return { ...preveState, client: action.data }; case "후기": return { posts: [...preveState.posts, action.data] }; default: return preveState; } }; const initialState = { client: { id: null, pasta: "주문내역없음", }, posts: [], }; const store = createStore(reducer, initialState); const handlePastaA = (data) => { //aciton return { type: "기본", data }; }; const handlePastaB = (data) => { //action return { type: "맵게", data }; }; const handlePastaC = (data) => { //action return { type: "로제", data }; }; const handlePosts = (data) => { return { type: "후기", data }; }; store.dispatch(handlePastaA("기본파스타")); console.log("기본", store.getState()); store.dispatch(handlePastaB("매운파스타")); console.log("맵게", store.getState()); store.dispatch(handlePastaC("로제파스타")); console.log("로제", store.getState()); store.dispatch(handlePosts({ id: 1, content: "맛있어요" })); console.log("후기", store.getState()); store.dispatch(handlePosts({ id: 2, content: "좋아요" })); console.log("후기두번째", store.getState());
분리한 코드
// src => index.js import { createStore } from "redux"; const initialState = { client: { id: null, pasta: "주문내역없음", }, posts: [], }; const store = createStore(reducer, initialState); store.dispatch(handlePastaA("기본파스타")); console.log("기본", store.getState()); store.dispatch(handlePastaB("매운파스타")); console.log("맵게", store.getState()); store.dispatch(handlePastaC("로제파스타")); console.log("로제", store.getState()); store.dispatch(handlePosts({ id: 1, content: "맛있어요" })); console.log("후기", store.getState()); store.dispatch(handlePosts({ id: 2, content: "좋아요" })); console.log("후기두번째", store.getState());
Action
// src => components => action => pasta.js export const handlePastaA = (data) => { //aciton return { type: "기본", data }; }; export const handlePastaB = (data) => { //action return { type: "맵게", data }; }; export const handlePastaC = (data) => { //action return { type: "로제", data }; };
// src => components => action => post.js export const handlePosts = (data) => { return { type: "후기", data }; };
Reducer
// src => components => reducer => reducer.js export const reducer = (preveState, action) => { switch (action.type) { case "기본": return { ...preveState, client: action.data }; case "맵게": return { ...preveState, client: action.data }; case "로제": return { ...preveState, client: action.data }; case "후기": return { posts: [...preveState.posts, action.data] }; default: return preveState; } };
이렇게 action 과 reducer를 나누어주었다. index에 코드량이 줄면서 가독성이 높은 걸 느낄 수 있었다. 하지만 action은 세분화하게 나누어주었지만 reducer는 그러지 못했다. 일단 하나의 state로 관리해야하는 redux 특성상 저걸 나눌 수 가없었다. 그래서 찾아보니 combineReducers를 알 수 있었다.
combineReducers
combineReducers란 서로 다른 reducer 함수들을 값으로 가지는 객체를 받아서 store(createStore)에 넘길 수 있는 하나의 reducer 함수로 바꾸어준다.
// scr => componets => reducer.js import { combineReducers } from "redux"; import { postReducer } from "./PostReducer"; import { pastaReducer } from "./UserReducer"; export const reducer = combineReducers({ posts: postReducer, client: pastaReducer, }); // reducer를 세세하게 나눈다 // combineReducer로 합친다. // 객체에 post:, client: 인 부분은 preveState=initialState를 각 reducer 별로 지정해준것이다. // 고로 우리는 구조분해 할당화된 코드를 작성할 수 있다.
// src => components => post.js const initialState = []; export const postReducer = (preveState = initialState, action) => { switch (action.type) { case "후기": return [...preveState, action.data]; // posts에 배열을 그대로 유지하면서 posts는 구조분해 할당화 되었으니깐 default: return preveState; } };
// src => components => pasta.js const initialState = { id: null, pasta: "주문내역없음", }; export const pastaReducer = (preveState = initialState, action) => { switch (action.type) { case "기본": return { ...preveState, pasta: action.data }; case "맵게": return { ...preveState, pasta: action.data }; case "로제": return { ...preveState, pasta: action.data }; default: return preveState; } };
주의! 세분화된 reducer에 꼭 combineReducer로 만든 객체에 지정한 initialState를 지정해주어야 한다.