[react] Redux의 구조 (Ducks구조 및 containers와 components)

eunbi·2020년 8월 7일
0

React

목록 보기
21/22

리덕스 모듈과 Ducks구조

  • 액션 타입
  • 액션 생성 함수
  • 리듀서

리덕스 모듈이란 위 항목들을 포함하는 파일을 의미한다.

Ducks 구조는 리듀서와 액션 관련 코드들을 하나의 파일에 모두 작성하는 구조이다.

1. modules 파일 안에 각 리덕스 모듈을 만든다.

액션 타입

const INCREASE = 'counter/increase';
const DECREASE = 'counter/decrease';

위처럼 접두사를 넣어주는 이유는 다른 모듈과 액션 이름이 중복되는 것을 방지하기 위함이다.

액션 생성 함수

export const increase = () => ({ type: INCREASE });
export const decrease = () => ({ type: DECREASE });

리듀서

export default function counterReducer(state = initialState, action) {
  switch (action.type) {
    case INCREASE:
      return {
        ...state,
        number: state.number + state.diff,
      };

    case DECREASE:
      return {
        ...state,
        number: state.number - state.diff,
      };
      
    default:
      return state;

useReducer 에선 일반적으로 default 부분에 error를 발생시켰지만 리덕스에서는 state를 반환하는데 이는 여러개의 서브 리듀서를 루트 리듀서로 합쳐서 하나로 만들기 때문이다. (루트 리듀서 안의 작은 리듀서들은 서브 리듀서라고 부른다.)

2. modules/index.js파일에서 root 리듀서를 만든다.

아래는 여러개의 서브 리듀서를 하나로 합쳐 root 리듀서를 만드는 과정이다.

import { combineReducers } from "redux";
import counterReducer from "./counter";
import todoReducer from "./todo";

const rootReducer = combineReducers({
  counterReducer,
  todoReducer,
});

export default rootReducer;

redux에서 combineReducers를 불러와 하나로 합칠 수 있다.

참고로 modules 내부에 있는 index.js를 불러올 때는 아래처럼 modules/index.js 경로를 생략하고 modules만 불러와도 자동으로 index 파일을 읽는다.

rootReducer from modules

3. 프리젠테이셔널 컴포넌트와 컨테이너 컴포넌트

우선 아래와 같이 react에서 redux를 사용하기 위해 react-redux를 설치해야한다.

yarn add react-redux

리덕스에서는 보통 프리젠테이셔널 컴포넌트와 컨테이너 컴포넌트로 나눈다.

프리젠테이셔널 컴포넌트란, 리덕스 스토어에 직접적으로 접근하지 않고 필요한 값 또는 함수를 props로 만 받아와서 사용하는 컴포넌트이다. 보통 components 디렉터리 안에 생성한다.

컨테이너 컴포넌트란, 리덕스 스토어의 상태를 조회하거나, 액션을 디스패치 할 수 있는 컴포넌트를 의미한다. 그리고, HTML 태그들을 사용하지 않고 다른 프리젠테이셔널 컴포넌트들을 불러와서 사용한다.
보통 containers 디렉터리 안에 생성한다.

분리의 장점

  1. 유지보수가 쉽다.
    각 컴포넌트가 자신의 역할이 명확하기 때문에 어떤 에러가 발생했을 시 어떤 컴포넌트를 고쳐야하는 지 확인하기 쉽다.
    예) container는 리덕스로부터 데이터를 받고 action을 실행하는 역할만을 전담하고, component는 리덕스의 state가 어떻든 상관하지 않고 그저 사용자와 상호작용한 후 정보를 받아서 Container로 넘겨준다.

  2. 성능이 좋아진다.
    컴포넌트가 복잡해짐에 따라 여러 개로 나누게 된다면, 업데이트가 컴포넌트 별로 일어나기 때문에 잘게 쪼갤수록 불필요한 컴포넌트의 업데이트를 방지할 수 있다.
    예) Container는 앱의 상태가 자주 바뀔수록 그에 따라 업데이트가 일어난다. 그래서 필요없는 부분에 업데이트가 일어나지 않게 하려면 Container과 Component를 구분해주어야 한다. Container가 업데이트되어도 그 아래 Component와 상관이 없다면 업데이트가 일어나지 않는다.

분리의 단점

코드가 분리되어 용량이 조금 증가되고 코드의 양이 많아지는 만큼 추적이 어려워질 수 있다. 또한 Container에서 Component로 데이터를 보내는 부분이 중복의 느낌이 있습니다. (props를 전달하는 과정에서 생기는 중복)

참고
https://www.zerocho.com/category/React/post/57e1428c11a9b10015e803aa
https://react.vlpt.us/redux/05-counter.html

profile
프론트엔드 개발자입니다 :)

0개의 댓글