티스토리 뷰

Redux 미들웨어

리덕스에서 dispatch를 하면 action 이 리듀서로 전달이 되고, 리듀서는 새로운 state를 반환하기 전 미들웨어 예시 이미지

  • Redux 미들웨어는 Redux 스토어에 전달되는 액션들을 가로채는 역할을 통해 액션 수정, 비동기 작업 처리, 액션을 디스패치하기 전 후에 특정 작업을 수행할 수 있다 (액션처리기로 생각할 것)
  • 주로 Redux-thunk를 사용하며 서버와의 통신을 위해 사용한다

thunk

  • thunk를 사용하면 dispatch를 할 때 객체가 아닌 함수를 dispatch 할 수 있게 해 준다.
  • dispatch(객체) X => dispatch(함수) O
  • thunk를 이용해 중간에 원하는 작업을 함수를 통해 넣을 수 있게 되며 이것을 이 함수를 thunk 함수라고 한다

thunk 예시코드

  • createAsyncThunk API로 thunk 함수 생성
  • 첫 번째 인자에는 Action Value, 두 번째 인자에는 함수가 들어간다(이 함수에 원하는 작업을 넣으면 됨)
  • 두 번째 인자인 함수에서도 인자를 꺼낼 수 있으며 첫 번째 인자(arg)는  thunk함수가 외부에서 사용되었을 때 넣은 값을 조회할 수 있고, 두 번째 인자에서는 thnuk가 제공하는 여러 가지 API 기능들이 담긴 객체를 꺼낼 수 있다.
// src/redux/modules/counterSlice.js

import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";

export const __addNumber = createAsyncThunk(

  "addNumber", // 첫번째 인자 : action value

(payload, thunkAPI) => {// 두번째 인자 : 콜백함수 
    setTimeout(() => {
      thunkAPI.dispatch(addNumber(payload));
    }, 3000);
  }
);

const initialState = {
  number: 0,
};

const counterSlice = createSlice({
  name: "counter",
  initialState,
  reducers: {
    addNumber: (state, action) => {
      state.number = state.number + action.payload;
    },

    minusNumber: (state, action) => {
      state.number = state.number - action.payload;
    },
  },
});

export const { addNumber, minusNumber } = counterSlice.actions;
export default counterSlice.reducer;

 

  • 위 코드에서 만든 thunk 함수사용 방법
  • thunk 함수 디스패치(첫 번째 인자인 action value를 넣어주면 된다)
  • payload는 thunk함수에 넣어주면, 리덕스 모듈에서 payload로 받을 수 있다.
  • 버튼을 클릭하면 thunk 함수의 setTimeout이 작동하며 3초 뒤 +1이 작동된다
  const onClickAddNumberHandler = () => {
    dispatch(__addNumber(number));
  };

 

thunk 함수사용 전체 코드

// src/App.jsx

import React from "react";
import { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { minusNumber, __addNumber } from "./redux/modules/counterSlice";

const App = () => {
  const dispatch = useDispatch();
  const [number, setNumber] = useState(0);
  const globalNumber = useSelector((state) => state.counter.number);

  const onChangeHandler = (evnet) => {
    const { value } = evnet.target;
    setNumber(+value);
  };

  const onClickAddNumberHandler = () => {
    dispatch(__addNumber(number));
  };

  const onClickMinusNumberHandler = () => {
    dispatch(minusNumber(number));
  };

  return (
    <div>
      <div>{globalNumber}</div>
      <input type="number" onChange={onChangeHandler} />
      <button onClick={onClickAddNumberHandler}>더하기</button>
      <button onClick={onClickMinusNumberHandler}>빼기</button>
    </div>
  );
};

export default App;

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함