[React] Thunk

J·2023년 5월 14일
0

React

목록 보기
19/25
post-thumbnail
  • 미들웨어란?

    • 소프트웨어에서 어떤 작업을 수행하기 전과 후에 발생하는 이벤트를 가로채는 소프트웨어 컴포넌트. 이를 통해 여러 가지 작업을 수행할 수 있음.
  • 리덕스 미들웨어

    https://react.vlpt.us/redux-middleware/

    • 리덕스에서의 미들웨어는 Action과 Reducer 사이에서 동작함. 액션 객체를 가로채서 추가 작업을 수행할 수 있음. 이를 통해 비동기 작업 처리, 로깅, 에러 처리 등의 추가 작업을 쉽게 구현할 수 있음.
  • thunk란?

    • 리덕스에서 많이 사용하는 미들웨어 중 하나. thunk를 사용하면 dispatch 할 때 객체가 아닌 함수를 dispatch 할 수 있게 해줌.
    • dispatch(객체)가 아닌 dispatch(함수)를 통해 action과 reducer 사이에 하고 싶은 작업을 함수를 통해 넣을 수 있고 그것이 중간에 실행이 되는 것.
      dispatch(함수) → 함수실행 → 함수안에서 dispatch(객체)
  • 사용해보기

    • 순서

      1. thunk 함수 만들기.
      2. extraReducer에 thunk 등록하기.
      3. dispatch(thunk 함수)하기.
    • createAsyncThunk API를 사용해 thunk 함수를 생성할 수 있음. API는 함수인데 첫 번째 인자에는 Action Value, 두 번째 인자에는 함수가 들어감. 이 함수에 하고 싶은 작업을 넣으면 됨.

    • 두 번째 들어가는 함수에도 인자를 꺼낼 수 있는데 첫 번째 인자(arg)는 이 thunk함수가 외버에서 사용되었을 때 넣은 값을 여기에서 조회할 수 있고 두 번째 인자(thunkAPI)에서는 thunk가 제공하는 여러가지 API 기능들이 담긴 객체를 꺼낼 수 있음.

      // thunk 함수는 createAsyncThunk 라는 툴킷 API를 사용해서 생성합니다.
      
      // __가 함수 이름에 붙는 이유는 이 함수가 thunk 함수라는 것을 표시하기 위한 
      // 개인의 convention 입니다. 함수의 이름은 본인이 편한 이름으로 명명하세요.
      
      export const __addNumber = createAsyncThunk(
      	"ADD_NUMBER_WAIT",
      	(arg, thunkAPI)=>{},
      );
    • counterSlice.js

      // src/redux/modules/counterSlice.js
      
      import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
      
      export const __addNumber = createAsyncThunk(
      	// 첫번째 인자 : action value
        "addNumber", 
      	// 두번째 인자 : 콜백함수 
        (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;
    • App.jsx

      // 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);
        };
      
        // thunk 함수를 디스패치한다. payload는 thunk함수에 넣어주면,
        // 리덕스 모듈에서 payload로 받을 수 있다.
        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;
    • 정리

      • 리덕스 미들웨어를 사용하면 action이 reducer로 전달되기 전 중간에 작업을 추가할 수 있음.

      • Thunk를 사용하면 객체가 아닌 함수를 dispatch 할 수 있음.

      • 툴킷에서 Thunk 함수를 생성할 때는 createAsyncThunk API 사용.

      • 두 번째 들어가는 함수에서 2개의 인자를 꺼내 사용할 수 있는데, 첫 번째 인자는 컴포넌트에서 보내준 payload, 두 번째 인자는 thunk에서 제공하는 여러가지 기능.

        • dispatch : thunk 함수 안에서 dispatch 할 때 사용.
        • getState : thunk 함수 안에서 현재 리덕스 모듈의 state 값을 사용하고 싶을 때 사용.
  • Thunk에서 Promise 다루기.

profile
벨로그로 이사 중

0개의 댓글