33일차(Thunk)

Undong·2023년 5월 6일
0

항해구구

목록 보기
33/52
post-thumbnail

항해 33일차

오늘은 시험을 보았다. 시험 내용에서는 Thunk에 대해서 나왔다. 거의 공부를 안한 부분이어서 공부를 하면서 시험을 진행하였다.

Thunk에 대해서 보자면 리덕스에서 많이 사용하고 있는 미들웨어 중에 하나이다. 여기서 미들웨어는 리덕에서 dispatch를 하면 action이 리듀서로 전달이 되고 리듀서는 새로운 state를 반환한다. 이때 미들웨어를 사용하면 이 과정 사이에서 우리가 하고 싶은 작업들을 넣어서 사용할 수 있다.

Thunk

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

예시로 보자면

  • createAsyncThunk은 비동기작업을 처리하는 action creator를 만듭니다.
  • action creator는 아래와 같이 3가지 상태를 갖습니다.
  • action creator.pending는 대기상태를 의미합니다.
  • action creator.fulfilled 는 완료 상태를 의미합니다.
  • action creator.rejected는 오류 상태를 의미합니다.
  • thunk는 각각의 상태에 따른 reducer를 체계적으로 작성할 수 있도록 유도합니다.
  • thunk를 처리할 때는 extraReducers를 사용합니다.

예시

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

/**
 * 2초 지연을 시키는 함수입니다 (비동기 작업).
 */
import { waitTwoSeconds } from "../../utils";

export const __addToDo = createAsyncThunk(
  "__addToDo",
  async (payload, thunkAPI) => {
    await waitTwoSeconds();
    return payload;
  }
);

export const __deleteTodo = createAsyncThunk(
  "__deleteToDo",
  async (payload, thunkAPI) => {
    await waitTwoSeconds();
    return payload;
  }
);

const initialState = {
  list: [],
};

const todosSlice = createSlice({
  name: "todos",
  initialState,
  reducers: {
    addTodo: (state, action) => {
      state.list.push(action.payload); // 새로운 할 일 객체를 추가합니다.
    },
    deleteTodo: (state, action) => {
      state.list = state.list.filter((todo) => todo.id !== action.payload);
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(__addToDo.fulfilled, (state, action) => {
        state.list.push(action.payload); // 새로운 할 일 객체를 추가합니다.
      })
      .addCase(__deleteTodo.fulfilled, (state, action) => {
        state.list = state.list.filter((todo) => todo.id !== action.payload); // 선택한 할 일 객체를 삭제합니다.
      });
  },
});

export const { addTodo, deleteTodo } = todosSlice.actions;
export default todosSlice.reducer;

profile
console.log("Hello")

0개의 댓글