Jello's development blog

Jello's development blog

Redux의 ducks패턴에 대해서

Ducks pattern

Redux를 사용하는 어플리케이션을 구축하다 보면 기능별로 여러 개의 액션 타입과, 액션, 리듀서 한 세트를 만들어야 한다. 이들은 관습적으로 여러 개의 폴더로 나누어져서, 하나의 기능을 수정할 때는 이 기능과 관련된 여러 개의 파일을 수정해야 하는 일이 생긴다. 여기서 불편함을 느껴 나온 것이 Ducks 구조이다.

Example

// widgets.js

// Actions
const LOAD   = 'my-app/widgets/LOAD';
const CREATE = 'my-app/widgets/CREATE';
const UPDATE = 'my-app/widgets/UPDATE';
const REMOVE = 'my-app/widgets/REMOVE';

// Reducer
export default function reducer(state = {}, action = {}) {
  switch (action.type) {
    // do reducer stuff
    default: return state;
  }
}

// Action 생성자
export function loadWidgets() {
  return { type: LOAD };
}

export function createWidget(widget) {
  return { type: CREATE, widget };
}

export function updateWidget(widget) {
  return { type: UPDATE, widget };
}

export function removeWidget(widget) {
  return { type: REMOVE, widget };
}

rules of Duck pattern

Ducks 구조에는 몇 가지 규칙이 있다.

하나의 모듈은…

  1. 항상 reducer()란 이름의 함수를 export default 해야한다.
  2. 항상 모듈의 action 생성자들을 함수형태로 export 해야한다.
  3. 항상 npm-module-or-app/reducer/ACTION_TYPE 형태의 action 타입을 가져야한다.
  4. 어쩌면 action 타입들을 UPPER_SNAKE_CASEexport 할 수 있다.

Ducks 구조가 관습적인 구조와 비교하여 가지는 차이점은, 구조 중심이 아니라 기능(모듈) 중심으로 파일을 나눈다는 것이다. 이 구조가 가지는 장점은, 단일 기능을 작성할 때나 바뀌었을 때에 하나의 파일만 다루면 되므로 좀 더 직관적인 코드 작성이 가능하다는 것이다. (코드가 직관적이고 읽기 쉽게 변했다.)

extensible-duck, redux-duck 같은 구현체가 있으니 사용해보면 괜찮을 것 같다.