combineReducers & 구조잡기

노영완·2023년 2월 9일
0

Redux

목록 보기
2/7
post-custom-banner

우리가 코드를 짜면서 많은 것을 신경쓰고 유의해야 할 것이 있다. 그 중 하나가 가독성 높은 코드 유지보수가 좋은 코드이다.

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를 지정해주어야 한다.

post-custom-banner

0개의 댓글