항해/TIL

TIL(2/27) / thunk

yeeendy 2024. 2. 27. 23:31

리덕스 thunk

리덕스 미들웨어 중 하나로 thunk를 사용하면 액션이 리듀서로 전달되기 전에 중간에 어떤 작업을 더할 수 있다.

객체가 아닌 함수를 dispatch!

 

thunk 흐름

dispatch(함수) -> 함수실행 -> 함수 안에서 dispatch(객체)

 

사용방법

툴킷 API인 createAsyncThunk import해오기

함수 명은 __를 붙여 작성하는 것이 thunk convention이다.

 

예시

// 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;
// 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;

 

정리

  • 리덕스 미들웨어를 사용하면, 액션이 리듀서로 전달되기전에 중간에 어떤 작업을 더 할 수있다.
  • Thunk를 사용하면, 객체가 아닌 함수를 dispatch 할 수 있게 해준다. [thunk의 핵심]
  • 리덕스 툴킷에서 Thunk 함수를 생성할 때는 **createAsyncThunk 를 이용한다.**
  • **createAsyncThunk() 의 첫번째 자리에는 action value, 두번째에는 함수가 들어간다.**
  • 두번째로 들어가는 함수에서 2개의 인자를 꺼내 사용할 수 있는데, 첫번째 인자는 컴포넌트에서 보내준 payload이고, 두번째 인자는 thunk에서 제공하는 여러가지 기능이다.
  • dispatch: thunk 함수안에서 dispatch를 할 때 사용
  • getState: thunk 함수안에서 현재 리덕스 모듈의 state 값을 사용하고 싶을 때 사용