1-10. 서브 리듀서 만들기

우리의 첫 리덕스 프로젝트는 끝이 났지만 아직 공부는 끝나지 않았습니다. 기존 리듀서를 색상 리듀서, 그리고 숫자 리듀서로 분리를 시킨다음에, combineReducers 를 통해 이를 합쳐서 루트 리듀서로 만드는 방법을 알아보겠습니다.

우선, reducers 디렉토리에 color.jsnumber.js 파일을 다음과 같이 만드세요.

src/reducers/color.js

import * as types from '../actions/ActionTypes';

const initialState = {
    color: 'black'
};

const color = (state = initialState, action) => {
    switch(action.type) {
        case types.SET_COLOR:
            return {
                color: action.color
            };
        default:
            return state;
    }
}

export default color;

src/reducers/number.js

import * as types from '../actions/ActionTypes';

const initialState = {
    number: 0
};

const number = (state = initialState, action) => {
    switch(action.type) {
        case types.INCREMENT: 
            return {
                number: state.number + 1
            };
        case types.DECREMENT:
            return {
                number: state.number - 1
            };
        default:
            return state;
    }
}

export default number;

그 다음에, reducers 디렉토리의 index.js 에서 redux 의 combineReducers 를 불러온뒤 다음과 같이 호출하세요.

src/reducers/index.js

import number from './number';
import color from './color';

import { combineReducers } from 'redux';

/*
    서브 리듀서들을 하나로 합칩니다.
    combineReducers 를 실행하고 나면, 나중에 store의 형태가 파라미터로 전달한 객체의 모양대로 만들어집니다.
    지금의 경우:
    {
        numberData: {
            number: 0
        },
        colorData: {
            color: 'black'
        }
    }
    로 만들어집니다.
*/



const reducers = combineReducers({
    numberData: number,
    colorData: color
});

export default reducers;

combineReducers 는 여러개의 서브리듀서를 하나로 합쳐줍니다. 이 과정에서 함수에 객체를 전달하게 되는데, 이 객체의 구조에 따라 합쳐진 리듀서의 상태의 구조가 만들어집니다.

따라서, 지금의 구조대로라면 기존 프로젝트가 작동하지 않겠죠?

그럼, ContactContainer 컴포넌트의 mapStateToProps 함수를 조금 수정해줍시다:

src/containers/ContactContainer.js

import Counter from '../components/Counter';
import * as actions from '../actions';
import { connect } from 'react-redux';
import { getRandomColor } from '../utils';

// store 안의 state 값을 props 로 연결해줍니다.
const mapStateToProps = (state) => ({
    color: state.colorData.color,
    number: state.numberData.number
});


/* 
    액션 생성자를 사용하여 액션을 생성하고,
    해당 액션을 dispatch 하는 함수를 만들은 후, 이를 props 로 연결해줍니다.
*/
const mapDispatchToProps = (dispatch) => ({
    onIncrement: () => dispatch(actions.increment()),
    onDecrement: () => dispatch(actions.decrement()),
    onSetColor: () => {
        const color = getRandomColor();
        dispatch(actions.setColor(color));
    }
});

// Counter 컴포넌트의 Container 컴포넌트
// Counter 컴포넌트를 어플리케이션의 데이터 레이어와 묶는 역할을 합니다.
const CounterContainer = connect(
    mapStateToProps,
    mapDispatchToProps
)(Counter);


export default CounterContainer;

자, 리듀서를 분리하는 연습도 마쳤습니다.

이제, 2장으로 넘어가서 조금 더 복잡한 상태를 관리해봅시다!

지금까지 작성한 코드는 https://github.com/vlpt-playground/redux-counter/tree/single-counter 에서 열람 할 수 있습니다.

results matching ""

    No results matching ""