thunk 소개

박서현·2023년 9월 13일
0
post-thumbnail
post-custom-banner

thunk란?

  • dispatch할 때 객체가 아닌 함수를 dispatch할 수 있게 해준다.
  • 중간에 우리가 하고자 하는 작업을 함수를 통해 넣을 수 있고, 그것이 중간에 실행되는것이다.
    dispatch(함수) → 함수실행 → 함수안에서 dispatch(객체)

기본 코드


📁 index.js

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { Provider } from "react-redux";
import store from "./redux/config/configStore";

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

reportWebVitals();

📁 App.jsx

import logo from "./logo.svg";
import "./App.css";
import { useDispatch, useSelector } from "react-redux";
import { addNumber, minusNumber } from "./redux/modules/counter";
import { useState } from "react";

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

  const dispatch = useDispatch();

  const onPlusButtonclickHandler = () => {
    dispatch(addNumber(+number));
  };

  const onMinusButtonClickHandler = () => {
    dispatch(minusNumber(+number));
  };

  return (
    <div>
      <div>{globalNumber}</div>
      <input
        type="number"
        onChange={(e) => {
          setNumber(e.target.value);
        }}
      />
      <br />
      <button onClick={onPlusButtonclickHandler}>더하기</button>
      <button onClick={onMinusButtonClickHandler}>빼기</button>
    </div>
  );
}

export default App;

📁 redux / config / configStore.js

import counter from "../modules/counter";

const { configureStore } = require("@reduxjs/toolkit");

const store = configureStore({
  reducer: {
    counter: counter,
  }
})

export default store;

📁 redux / modules / counter.js

import { createSlice } from "@reduxjs/toolkit"

// 초기 상태(state)
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 default counterSlice.reducer
export const {addNumber, minusNumber} = counterSlice.actions


순서

  1. thunk 함수 만들기 : createAsyncThunk
  • reduxToolkit 내장 API
  1. createSlice > extraReducer에 thunk 등록
  2. dispatch
  3. 테스트

실습

📁 redux / modules / counter.js

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

//2개의 input
// (1) 이름 : 의미는 크게 없음
// (2) 함수
export const __addNumber = createAsyncThunk(
  "ADD_NUMBER_WAIT",
  (payload, thunkAPI) => {
    // 수행하고 싶은 동작 : 3초 기다리게 할 예정
    setTimeout(() => {
      thunkAPI.dispatch(addNumber(payload));
    }, 3000);
  }
);

export const __minusNumber = createAsyncThunk(
  "MINUS_NUMBER_WAIT",
  (payload, thunkAPI) => {
    // 수행하고 싶은 동작 : 3초 기다리게 할 예정
    setTimeout(() => {
      thunkAPI.dispatch(minusNumber(payload));
    }, 3000);
  }
);

// 초기 상태(state)
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 default counterSlice.reducer;
export const { addNumber, minusNumber } = counterSlice.actions;

📁 App.jsx

import "./App.css";
import { useDispatch, useSelector } from "react-redux";
import { useState } from "react";
import { __addNumber, __minusNumber } from "./redux/modules/counter"; // 추가

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

  const dispatch = useDispatch();

  const onPlusButtonclickHandler = () => {
    dispatch(__addNumber(+number)); // 수정
  };

  const onMinusButtonClickHandler = () => {
    dispatch(__minusNumber(+number)); // 수정
  };

  return (
    <div>
      <div>{globalNumber}</div>
      <input
        type="number"
        onChange={(e) => {
          setNumber(e.target.value);
        }}
      />
      <br />
      <button onClick={onPlusButtonclickHandler}>더하기</button>
      <button onClick={onMinusButtonClickHandler}>빼기</button>
    </div>
  );
}

export default App;


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

post-custom-banner

0개의 댓글