[React/Redux] redux-saga

Bam·2022년 3월 9일
0

React

목록 보기
31/40
post-thumbnail

발생자 Generator

redux-saga 미들웨어는 Generator 문법을 사용해서 비동기 처리를 관리해줍니다. 그러므로 미들웨어를 공부하기 전에 발생자에 대한 문법과 개념을 알아두어야합니다. 발생자 문법과 설명은 발생자 포스트를 참조해주세요.

redux-saga

redux-thunk에 이어서 또 다른 비동기 처리를 담당하는 리덕스 미들웨어 redux-saga를 알아보겠습니다.

yarn을 통해 redux-saga를 설치해주세요.

yarn add redux-saga

redux-saga 사용하기

redux-thunk에서 사용했던 ColorChanger 앱을 redux-saga를 적용시킨 어플리케이션으로 변경해보겠습니다.

우선 modules의 코드에서 액션, 액션 생성 함수를 다시 정의하고 제너레이터까지 만들어보겠습니다.

import {createAction, handleActions} from 'redux-actions';
import {delay, put, takeEvery} from 'redux-saga/effects';

const SET_COLOR_BLACK = 'colorChangerMW/SET_COLOR_BLACK';
const SET_COLOR_BLUE = 'colorChangerMW/SET_COLOR_BLUE';
const SET_COLOR_RED = 'colorChangerMW/SET_COLOR_RED';

const SET_COLOR_BLACK_ASYNC = 'colorChangerMW/SET_COLOR_BLACK_ASYNC';
const SET_COLOR_BLUE_ASYNC = 'colorChangerMW/SET_COLOR_BLUE_ASYNC';
const SET_COLOR_RED_ASYNC = 'colorChangerMW/SET_COLOR_RED_ASYNC';

export const setColorBlack = createAction(SET_COLOR_BLACK);
export const setColorBlue = createAction(SET_COLOR_BLUE);
export const setColorRed = createAction(SET_COLOR_RED);

//두 번째 인자의 함수는 클릭 이벤트가 payload에 들어가는 것을 막기 위함!
export const setColorBlackAsync = createAction(SET_COLOR_BLACK_ASYNC, () => undefined);
export const setColorBlueAsync = createAction(SET_COLOR_BLUE_ASYNC, () => undefined);
export const setColorRedAsync = createAction(SET_COLOR_RED_ASYNC, () => undefined);

function* setColorBlackSaga() {
    yield delay(1000);
    yield put(setColorBlack());  //액션 디스패치
}

function* setColorBlueSaga() {
    yield delay(1000);
    yield put(setColorBlue());
}

function* setColorRedSaga() {
    yield delay(1000);
    yield put(setColorRed());
}

export function* colorChangerSaga() {
    //takeEvery: 모든 액션에 대해 작업 처리
    yield takeEvery(SET_COLOR_BLACK_ASYNC, setColorBlackSaga);
    yield takeEvery(SET_COLOR_BLUE_ASYNC, setColorBlueSaga);
    yield takeEvery(SET_COLOR_RED_ASYNC, setColorRedSaga);
}

const initialState = {
    text: '검정',
    color: '#000',
};

const colorChangerMW = handleActions(
    {
        [SET_COLOR_BLACK]: (state, action) => ({
            text: '검정',
            color: '#000',
        }),
        [SET_COLOR_BLUE]: (state, action) => ({
            text: '파랑',
            color: '#00f',
        }),
        [SET_COLOR_RED]: (state, action) => ({
            text: '빨강',
            color: '#f00',
        }),
    },
    initialState
);

export default colorChangerMW;

다음으로는 modules/index.js에서 루트 사가(Root Saga)를 만들어 줍니다. 루트 사가는 루트 리듀서 처럼 여러 개의 사가들을 하나로 묶는 역할을 해줍니다.

import {combineReducers} from 'redux';
import {all} from 'redux-saga/effects';
import colorChangerMW, {colorChangerSaga} from './colorChangerMW';

const rootReducer = combineReducers({
    colorChangerMW,
});

//루트 사가
export function* rootSaga() {
    //all은 Saga들을 합쳐줍니다.
    yield all([colorChangerSaga()]);
}

export default rootReducer;

여기까지 완료되었다면, src/index.js에서 스토어를 수정해주어야합니다.

// ...이상 import문 생략
import createSagaMiddleWare from 'redux-saga';

const logger = createLogger();
const sagaMiddleware = createSagaMiddleWare();
const store = createStore(rootReducer, applyMiddleware(logger, ReduxThunk, sagaMiddleware));

sagaMiddleware.run(rootSaga);

ReactDom.render(
    <Provider store={store}>
        <App/>
    </Provider>,
    document.getElementById('root'),
);

App.js를 실행했을 때 1초 뒤에 글자와 색상이 변경되면 올바르게 처리한 것 입니다. 그리고 개발자 도구를 열어 redux-logger로 log를 살펴볼 때 입력한 대로, 변하는대로 액션이 디스패치 되었나요?

0개의 댓글