저는 Redux 어플리케이션을 구축하는 과정에서, 한 번에 기능 한 부분을 만들 때, 각각의 use case에 따라 {actionTypes, actions, reducer}
한 벌을 계속 추가해야 된다는 것을 깨달았습니다. 저는 각각을 별도의 파일 심지어 폴더로 나누어두었지만, 95%의 경우에는 reducer/actions 한 쌍만이 서로 연관된 동작을 필요로 합니다.
제가 봤을 땐, 이러한 조각들이 포함된 하나의 독립된 모듈로 묶는 것이 더 의미가 있고, 라이브러리로 패키징하기에도 쉽습니다.
Common JS 예시도 참고하세요.
// 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 };
}
하나의 모듈은...
- 항상
reducer()
란 이름의 함수를export default
해야합니다. - 항상 모듈의 action 생성자들을 함수형태로
export
해야합니다. - 항상
npm-module-or-app/reducer/ACTION_TYPE
형태의 action 타입을 가져야합니다. - 어쩌면 action 타입들을
UPPER_SNAKE_CASE
로export
할 수 있습니다. 만약, 외부reducer
가 해당 action들이 발생하는지 계속 기다리거나, 재사용할 수 있는 라이브러리로 퍼블리싱할 경우에 말이죠.
재사용가능한 Redux 라이브러리 형태로 공유하는 {actionType, action, reducer}
묶음에도 위 규칙을 추천합니다.
Java에는 jars와 beans이 있습니다. Ruby에는 gems이 있고요. 저는 위와 같은 reducer 묶음을 "redux"의 마지막 음절을 따서 "ducks"라고 부르는 것을 제안합니다.
여전히 아래와 같이 사용할 수 있습니다.
import { combineReducers } from 'redux';
import * as reducers from './ducks/index';
const rootReducer = combineReducers(reducers);
export default rootReducer;
여전히 아래와 같이 사용할 수 있습니다.
import * as widgetActions from './ducks/widgets';
...그리고 bindActionCreators()
에 바로 넘겨줄 수 있도록 action 생성자만을 import
합니다.
그리고 어쩌면 action 생성자가 아닌 것을 export
하고 싶을 때가 있을 겁니다. 그것도 좋습니다. 위 규칙은 항상 action 생성자만을 export
하라고 말하는 것은 아닙니다. 만약 action 생성자가 아닌 것을 추가했을 경우엔, action 생성자들을 나열하면 됩니다. 별 것 아닙니다.
import {loadWidgets, createWidget, updateWidget, removeWidget} from './ducks/widgets';
// ...
bindActionCreators({loadWidgets, createWidget, updateWidget, removeWidget}, dispatch);
React Redux Universal Hot Example은 ducks를 따릅니다. /src/redux/modules
를 보세요.
이러한 코드 구조를 적용하는 것은 쉬웠습니다. 그리고 추후에 개발을 할 때에도 고통이 감소할 것이라고 예상합니다.
피드백을 환영합니다! issue를 통해 피드백을 남겨주시거나 @erikras에 트윗을 주시면 정말 감사하겠습니다.
즐거운 코딩하세요!
-- Erik Rasmussen
사진의 저작권은 Airwolfhound에게 있습니다.