Counter 프로젝트에 Redux를 적용해봅시다.
해당 페이지에서는 reducer.js 파일을 수정해 볼 것입니다. 먼저, redux-actions 라이브러리를 통해 redux 코드를 줄여봅시다. 그리고 리듀서 함수 내에서 불변성은 필수 요소입니다. 하지만 불변성을 지키는 만큼 코드도 매우 복잡해집니다. 이를 위한 라이브러리가 바로 Immer 입니다. Immer 외에도 Immutable 이라는 라이브러리도 존재하지만, get, set 함수 등을 통해 상태 값을 변경해야 한다는 불편함이 존재하기 때문에 여기에서는 Immer를 사용하겠습니다. Counter에 Redux 적용하기 (1) 페이지에서 redux-actions, Immer 라이브러리를 다운받았기 때문에 바로 reducer.js 파일을 수정하겠습니다. 아래와 같이 코드를 수정해주세요.
import { createAction, handleActions } from 'redux-actions';
import produce from 'immer';
const INCREASE = 'INCREASE';
const DECREASE = 'DECREASE';
export const increase = createAction(INCREASE, number => number);
export const decrease = createAction(DECREASE, number => number);
const initialState = {
number: 0
};
export default handleActions({
[INCREASE]: (state, action) =>
producer(state, draft => {
draft.number = action.payload
}),
[DECREASE]: (state, action) =>
producer(state, draft => {
draft.number = action.payload
})
}, initialState);
먼저 redux-actions 라이브러리에 존재하는 createAction 함수와 handleActions 함수에 대해 알아봅시다.
createAction
createAction 함수는 간편하게 액션 생성자를 만들어주는 함수입니다. 인자값으로 2가지를 넘겼는데, 하나는 액션 타입이고 다른 하나는 payloadCreator입니다. 액션 타입은 위에서 정의했던 액션 타입 상수를 넣었고, payloadCreator는 함수의 형태로 넘겨주었습니다. 어떤 데이터를 받는다는 것을 명시하기 위해 넣어주었습니다. payloadCreator는 생략 가능합니다.
handleActions
handleActions 함수는 Redux의 핵심 부분인 리듀서 부분을 더 간편하게 만들어주는 함수입니다. 인자값으로 2가지를 넘겼는데, 하나는 리듀서이고 다른 하나는 initialState 값입니다. 작동 방식은 Counter에 Redux 적용하기 (1) 페이지에서 만들었던 스위치문으로 작성된 리듀서와 동일합니다.
다음으로 Immer 라이브러리에 대해 알아봅시다. 위와 같이 Immer 라이브러리를 사용하면 마치 불변성을 신경 쓰지 않는 것처럼 코드를 짜도 상관없습니다. 알아서 불변성을 관리해주기 때문이죠. Immer의 동작 방식은 아래 사진과 같습니다.

현재 상태를 임시적인 Draft에 적용하고, 사용자는 이 Draft를 수정하게 됩니다. 수정 작업이 모두 완료되면 Draft를 통해 새로운 상태를 만들어 반환하는 것이죠. 이렇게 해서 불변성을 신경 쓰지 않는 것처럼 보이지만 실제로는 불변성이 잘 지켜지고 있는 것입니다.