본문 바로가기
Frontend/React

[React] 리액트 미들웨어란?

by 디스코비스킷 2023. 12. 28.
반응형

API 서버를 연동할때, 리덕스를 사용하고 있으며 이러한 비동기 작업을 관리해야한다면 미들웨어를 사용하여 매우 효율적이고 편하게 상태관리를 할 수 있다.

작업환경준비

프로젝트 만들기

$ mkdir react-middleware
$ cd react-middleware
$ npm init vite
$ npm install
$ npm install react-redux redux-actions

counter 리덕스 모듈

modules/counter.js

import { createAction, handleActions } from "redux-actions";

const INCREASE = "counter/INCREASE";
const DECREASE = "counter/DECREASE";

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

const initialState = 0;

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

export default counter;

루트리듀서 생성

modules/index.js

import { combineReducers } from 'redux';
import counter from './counter';

const rootReducer = combineReducers({
    counter
});

export default rootReducer;

스토어생성

main.jsx

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import rootReducer from './modules/index.js'
import { applyMiddleware, legacy_createStore as createStore } from "redux";
import { Provider } from 'react-redux';
import loggerMiddleware from './lib/loggerMiddleware.js';

const store = createStore(rootReducer, applyMiddleware(loggerMiddleware));

ReactDOM.createRoot(document.getElementById('root')).render(
  <Provider store={store}>
    <App />
  </Provider>
)

카운터 컴포넌트와 컨테이너

components/Counter.jsx

import React from 'react'

const Counter = ({ onIncrease, onDecrease, number }) => {
  return (
    <div>
        <h1>{number}</h1>
        <button onClick={onIncrease}>+1</button>
        <button onClick={onDecrease}>-1</button>
    </div>
    )
}

export default Counter

containers/CounterContainer.jsx

import React from 'react'
import Counter from '../components/Counter'
import { connect } from 'react-redux'
import { increase, decrease } from '../modules/counter'
const CounterContainer = ({ number, increase, decrease }) => {
    console.log("test")
  return (
    <Counter number={number} onIncrease={increase} onDecrease={decrease} />
  )
}

export default connect(
    state => ({
        number: state.counter
    }),
    {
        increase,
        decrease,
    }
)(CounterContainer);

App.jsx에서 CounterContainer를 렌더링하여 확인한다.

미들웨어란?

리덕스 미들웨어는 액션을 디스패치 했을때 리듀서에서 이를 처리하기에 앞서 사전에 지정된 작업을 실행한다. 미들웨어는 액션과 리듀서 사이의 중간자라고 볼 수 있다.

미들웨어 만들어보기

직접 만들어서 사용할일은 별로 없지만 미들웨어를 이해하기 위해 간단하게 만들어보겠다.

만들 로깅 미들웨어는

  • 액션이 디스패치 될 때마다
  • 액션의 정보와
  • 액션이 디스패치 되기 전후의 상태를
  • 콘솔에 보여준다.
// 미들웨어 기본구조
const loggerMiddleware = store => next => action => {
    console.group(action && action.type); // action 타임으로 log를 그룹화
    console.log('이전상태: ', store.getState());
    console.log('액션', action);
    next(action);
    console.log('다음상태: ', store.getState());
    console.groupEnd();
}

export default loggerMiddleware

main.jsx에서 미들웨어를 적용한다.

import { applyMiddleware, legacy_createStore as createStore } from "redux";
import loggerMiddleware from './lib/loggerMiddleware.js';

const store = createStore(rootReducer, applyMiddleware(loggerMiddleware));

ReactDOM.createRoot(document.getElementById('root')).render(
  <Provider store={store}>
    <App />
  </Provider>
)

미들웨어 특징

  • 미들웨어 내부에서 store.dispatch를 사용하면 첫번째 미들웨어부터 다시 처리한다. 만약 미들웨어에서 next를 사용하지 않으면 액션이 리듀서에 전달되지 않는다.
  • 여러종류의 작업을 처리할 수 있음
  • 특정조건에 따라 액션을 무시하게 할 수 있음
  • 특정조건에 따라 액션정보를 가로채서 변경한후, 리듀서에 전달할 수 있음
  • 특정액션에 기반하여 새로운 액션을 여러번 디스패치 할 수있음

이러한 미들웨어 속성을 사용하여 네트워크 요청과 같은 비동기 작업을 관리하면 매우 유용하다.

redux-logger

오픈소스 커뮤니티에 올라와있는 리덕스로거라는 라이브러리이다.
콘솔에 나타나는 형식도 깔끔하며 더 잘만들어졌다. 콘솔에 색상도 입혀지고, 액션 디스패치 시간도 나타난다.

$ npm install redux-logger

main.jsx

import { applyMiddleware, legacy_createStore as createStore } from "redux";
import { createLogger } from 'redux-logger';

const logger = createLogger();
const store = createStore(rootReducer, applyMiddleware(logger));
반응형

최근댓글

최근글

© Copyright 2023 jngmnj