# 시작
자바스크립트로 리덕스를 사용하면서 액션 -> 미들웨어 -> 리듀서 -> 스토어 -> 뷰 ->(반복) 의 순환을 이해해보았다.
# 과정
친구 목록 업데이트와 타임라인 페이지를 넘기는 것을 리덕스를 통해 처리했다.
코드를 입력한다음 아래와 같이 액션을 생성했다.
import { createStore, combineReducers } from "redux";
import timelineReducer, {
addTimeline,
removeTimeline,
editTimeline,
increaseNextPage,
} from "./timeline/state";
import friendReducer, {
addFriend,
removeFriend,
editFriend,
} from "./friend/state";
// @ : 친구 목록과 타임라인 모듈에서 액션 생성자 함수와 리듀서 함수를 가져온다.const reducer = combineReducers({
timeline: timelineReducer,
friend: friendReducer,
});
// @ : combineReducers 함수를 이용해 두개의 리듀서를 하나로 합친다. 상탯값에는 timeline, friend로 데이터 저장됨const store = createStore(reducer);
// @ : 스토어 생성
store.subscribe(() => {
const state = store.getState();
console.log(state);
});
// @ : 디버깅 위해 액션 처리가 끝날 때마다 상탯값을 로그로 출력한다.
store.dispatch(addTimeline({ id: 1, desc: "코딩은 즐거워" }));
store.dispatch(addTimeline({ id: 2, desc: "리덕스 좋아" }));
store.dispatch(addTimeline(increaseNextPage()));
store.dispatch(editTimeline({ id: 2, desc: "리덕스 너무 좋아" }));
store.dispatch(removeTimeline({ id: 1, desc: "코딩은 즐거워" }));
// @ : 타임라인 테스트를 위해 다섯개의 액션 생성
store.dispatch(addFriend({ id: 1, desc: "아이유" }));
store.dispatch(addFriend({ id: 2, desc: "손나은" }));
store.dispatch(editFriend({ id: 2, desc: "수지" }));
store.dispatch(removeFriend({ id: 1, desc: "아이유" }));
// @ : 친구 목록을 테스트하기 위해 네개의 액션을 생성
1. 타임라인에 코딩은 즐거워에 대한 객체가 추가된다.
2. 타임라인에 리덕스 좋아에 대한 객체가 추가된다.
3. 타임라인 끝에 도달하면 서버에 요청할 페이지 번호를 증가시킨다.
4. id: 2(리덕스 좋아) 라는 객체의 desc를 리덕스 너무 좋아로 변경한다.
5. id: 1(코딩은 즐거워)라는 객체를 삭제한다.
1. id: 1의 "아이유" 객체 추가
2. id: 2의 "손나은" 객체 추가
3. id: 2의 "아이유" 객체를 "수지"로 변경
4. id: 1의 객체를 삭제
콘솔은 아래와 같이 나타났다.
1. 타임라인에 코딩은 즐거워에 대한 객체가 추가된다.
2. 타임라인에 리덕스 좋아에 대한 객체가 추가된다.
3. 타임라인 끝에 도달하면 서버에 요청할 페이지 번호를 증가시킨다.
4. id: 2(리덕스 좋아) 라는 객체의 desc를 리덕스 너무 좋아로 변경한다.
5. id: 1(코딩은 즐거워)라는 객체를 삭제한다.
1. id: 1의 "아이유" 객체 추가
2. id: 2의 "손나은" 객체 추가
3. id: 2의 "아이유" 객체를 "수지"로 변경
4. id: 1의 객체를 삭제
combineReducers 함수를 이용해 리듀서별로 상탯값을 관리했다.
# 코드 리팩터링
import { combineReducers } from 'redux'// ...export default combineReducers({
common : reducer,
timelines: timelineReducers,
})
각 리듀서마다 새로운 이름을 부여하면서 객체의 깊이가 깊어진다.
이를 피하기 위해 mergeReducers를 사용한다.
export default function mergeReducers(reducers) {
// @ : mergeReducers는 리듀서를 반환한다.return function (state, action) {
if (!state) {
// @ : 초기 상탯값을 계산할 때는 모든 리듀서 함수의 결괏값을 합친다.return reducers.reduce((acc, r) => ({
...acc,
...r(state, action),
}));
} else {
// @ : 초기화 단계가 아니라면 입력된 모든 리듀서를 호출해서 다음 상탯값 반환let nextState = state;
for (const r of reducers) {
nextState = r(nextState, action);
}
return nextState;
}
};
}
이전과 같은 결과가 출력된다.