Redux-thunk 01 | 개념 / 미들웨어 적용

Kate Jung·2022년 1월 2일
0

middlewares & libraries

목록 보기
6/17
post-thumbnail
post-custom-banner

📌 Redux-thunk란?

(리덕스 사용 프로젝트에서) 비동기 작업 처리 시 (가장 기본적으로) 사용하는 미들웨어

  • 함수 형태의 액션 디스패치 가능

    액션 생성 함수에서 함수 반환(액션 객체 반환 대신)

  • 창시자

    댄 아브라모프(Dan Abramov)

  • Thunk란?

    의미: 특정 작업을 나중에 할 수 있도록 미루기 위해 함수 형태로 감싼 것


  • 사용 시

    thunk 함수 만들어서 디스패치 가능

    → 리덕스 미들웨어가 그 함수를 전달 받아 store의 dispatch와 getState를 파라미터로 넣어 호출

    • 예시 thunk 함수
        const sampleThunk = () => (dispatch, getState) => {
        	// 현재 상태 참조 가능
        	// 새 액션 디스패치 가능
        }

📌 미들웨어 적용

1. 설치

$ yarn add redux-thunk

2. 스토어에 redux-thunk적용 (index.js)

(생략)
**import ReduxThunk from 'redux-thunk';**

(생략)
const store = createStore(
  rootReducer,
  composeWithDevTools(applyMiddleware(logger, **ReduxThunk**)),
);

(생략)

3. Thunk 생성 함수 만들기 (modules/counter.js)

  • 카운터 값을 비동기적으로 변경

    increaseAsync, decreaseAsync 함수

  • 코드

    import { createAction, handleActions } from 'redux-actions';
    
    // 액션 타입
    const INCREASE = 'counter/INCREASE';
    const DECREASE = 'counter/DECREASE';
    
    // 액션 생성 함수
    export const increase = createAction(INCREASE);
    export const decrease = createAction(INCREASE);
    
    **// 1초 뒤에 increase 혹은 decrease 함수를 디스패치 함
    export const increaseAsync = () => (dispatch) => {
      setTimeout(() => {
        dispatch(increase());
      }, 1000);
    };
    export const decreaseAsync = () => (dispatch) => {
      setTimeout(() => {
        dispatch(decrease());
      }, 1000);
    };**
    
    // 초기 값
    const initialState = 0; // 상태는 꼭 객체일 필요 x. 숫자도 작동 가능
    
    // 리듀서
    const counter = handleActions(
      {
        [INCREASE]: (state) => state + 1,
        [DECREASE]: (state) => state - 1,
      },
      initialState,
    );

4. Container 컴포넌트의 액션 생성 함수 변경(container/CounterContainer.js)

import React from 'react';
import { connect } from 'react-redux';
import { **increaseAsync, decreaseAsync** } from '../modules/counter';
import Counter from '../components/Counter';

const CounterContainer = ({ number, **increaseAsync, decreaseAsync** }) => {
  return (
    <Counter
      number={number}
      onIncrease={**increaseAsync**}
      onDecrease={**decreaseAsync**}
    />
  );
};

export default connect(
  (state) => ({
    number: state.counter,
  }),
  {
    **increaseAsync,**
    **decreaseAsync,**
  },
)(CounterContainer);
  • 디스패치된 액션

    • 첫 번째 디스패치된 액션

      함수 형태

    • 두 번째 액션

      객체 형태

profile
복습 목적 블로그 입니다.
post-custom-banner

0개의 댓글