리덕스 미들웨어를 알아보자!

이상진·2023년 5월 27일
4

React

목록 보기
2/6
post-thumbnail

리액트를 다루는 기술

이번 글은 리액트를 다루는 기술 chapter 18을 기반으로 작성되었다.

미들웨어란?

미들웨어란 함수를 반환하는 함수를 반환하는 함수이다.

리덕스 미들웨어는 액션을 디스페치했을 때 리듀서에서 이를 처리하기에 앞서 사전에 지정된 작업들을 실행한다.

액션 -> 미들웨어 -> 리듀서 -> 스토어

const loggerMiddleware = (store) => (next) => (action) => {
	//미들웨어의 기본 구조
}
// 이전상태, 액션정보, 새로워진 상태를 콘솔에 찍는 예제

const loggerMiddleware = (store) => (next) => (action) => {
	console.log(action && action.type);
  	console.log('이전 상태', store.getState());
  	console.log('액션', action);
  	next(action);
  	console.log('다음상태', store.getState());
  	console.groupEnd();
}

export default loggerMiddleware;

미들웨어의 장점
1. 비동기 작업 관리
2. 액션 로깅 및 디버깅
3. 액션 변형
4. 코드의 재사용성과 모듈화
5. 확장성

미들웨어의 고려사항
1. 복잡성
2. 테스트의 어려움
3. 학습이 어려움

redux-logger 사용하기

redux-logger를 사용하면 loggerMiddelware보다 훨씬 더 보기 쉬운 형태가 된다. (콘솔에 색상, 액션 디스페치의 시간이 나타남)

import { createLogger } from 'redux-logger';

const logger = createLogger()

const store = createStore(reducer, applyMiddleware(logger))

redux-thunk

redux-thunk란 리덕스를 사용하는 프로젝트에서 비동기 작업을 처리할 때 가장 기본으로 사용하는 미들웨어이다.

Thunk란?
Thunk는 특정 작업을 나중에 할 수 있도록 미루기 위해 함수 형태로 감싼 것을 의미한다.

redux-thunk로 비동기 카운터 페이지 만들기

//redux-thunk 미들웨어 적용하기

import React from 'react';
import ReactDOM from 'react-dom/client';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import './index.css';
import App from './App';
import rootReducer from './modules';
import { createLogger } from 'redux-logger';
import ReduxThunk from 'redux-thunk';

const logger = createLogger();
const store = createStore(rootReducer, composeWithDevTools());

const root = ReactDOM.createRoot(document.getElementById(logger, ReduxThunk));
root.render(
  <Provider store={store}>
    <App />
  </Provider>
);

Thunk 생성 함수 만들기

redux-thunk 에서는 액션 생성 함수에서 일반 액션 객체를 반환하는 대신에 함수를 반환한다.

import { createAction,handleActions } from 'react-actions';

const INCREASE = 'counter/INCREASE';
const DECREASE = 'counter/DECREASE';

export const increase = () => (INCREASE);
export const decrease = () => (DECREASE);

export const increaseAsync = () => dispatch => {
  setTimeout(() => {
    dispatch(increase());
  }, 1000);
}
export const decreaseAsync = () => dispatch => {
  setTimeout(() => {
    dispatch(decrease());
  }, 1000);
}

const initialState = 0;

const counter = handleActions(
  {
    [INCREASE]: state => state + 1,
    [DECREASE]: state => state - 1
  },
  initialState
);

export default counter;

제네레이터 함수

redux-saga 에서 사용되는 문법이다.

이 문법의 핵심 기능은 함수를 작성할 때 함수를 특정 구간에 멈춰 놓을 수도 있고, 원할 때 다시 돌아가게 할 수도 있다.

function* generatorFunction() {
  console.log('하이');
  yield 1;
  console.log('파이');
  yield 2;
  console.log('브');
  yield 3;
  return 3;
}

제네레이터 함수에서는 function* 를 사용해야한다.

redux-saga

redux-saga 란 함수 형태의 액션을 디스패치하여 미들웨어에서 해당 함수에 스토어의 dispatch 와 getState를 파라미터로 넣어서 사용하는 방식이다.

redux-saga 는 redux-thunk 보다 조금 더 까다로운 상황에 유용하게 사용된다.

  1. 기존 요청을 취소 처리해야 할 때 (불필요한 중복 요청 방지)
  2. 특정 액션이 발생했을 때 다른 액션을 발생시키거나, API 요청 등 리덕스와 관계없는 코드를 실행할 때
  3. 웹소켓을 많이 사용할 때
  4. API 요청 실패 시 재요청해야 할 때

redux-saga로 비동기 카운터 페이지 만들기

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

const INCREASE_ASYNC = 'counter/INCREASE_ASYNC';
const DECREASE_ASYNC = 'counter/DECREASE_ASYNC';

const increaseAsync = createAction(INCREASE_ASYNC, () => undefined);
const decreaseAsync = createAction(DECREASE_ASYNC, () => undefined);

function* increaseSaga() {
  yield delay(1000);
  yield put(increase());
}

function* decreaseSaga() {
  yield delay(1000);
  yield put(decrease());
}

function* counterSaga() {
  yield takeEvery(INCREASE_ASYNC, increaseSaga);
  yield takeLatest(DECREASE_ASYNC, decreaseSaga);
}

const initialState = 0; // 상태는 꼭 객체일 필요가 없다. 

const counter = handleActions(
  {
	[INCREASE]: state => state + 1,
    [DECREASE]: state => state - 1
  },
  initialState
)

export default counter;

글을 마치며

redux-saga 와 redux-thunk 의 진입장벽이 매우 높은것 같다는 생각이 들었다..
언어 공부를 하면서 이렇게 안 와닿았던적이 있었나 싶을 정도로 이해가 쉽게 되지 않는 부분이였어서 앞으로도 쭉 리덕스 미들웨어에 대한 공부를 해야될것 같다는 생각이든다.

profile
프론트엔드 공부중

1개의 댓글

comment-user-thumbnail
2023년 5월 28일

인터뤠스튕~

답글 달기