React - 심화 : Thunk3 - 개인 프로젝트 적용

최문길·2023년 12월 19일
0

react

목록 보기
12/14

참고로- typescript를 사용해서 ReduxThunk를 사용하려면

  // TypeScript reduxThunk 권장 하는 방식
  extraReducers: (builder) => {
    builder
      .addCase(__getTodos.pending, (state, action) => {
        state.isLoading = true;
        state.isError = false;
      })
      .addCase(__getTodos.fulfilled, (state, action) => {
        state.isLoading = false;
        state.isError = false;
        state.todos = action.payload;
      })
      .addCase(__getTodos.rejected, (state, action) => {
        state.isLoading = false;
        state.isError = true;
        state.error = action.payload;
      });
  },
});

블로그에서 thunk에 관해 찾아보면 위의 코드와 같은 것을 자주 볼수 있는데, redux에서 typescript를 사용해서 thunk를 구현하고 싶으면 위의 방식대로 하라고 한다.

내가 만들었던 프로젝트에서 사용해보기

post를 get, post,delete,patch 하는 거였다.
서버는 json-server를 사용하였었다.


// src/redux/modules/postSlice.js

import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import postsAPI from "../../API/posts.api";

const initialState = {
  posts: [],
  isLoading: false,
  error: {
    status: null,
    isError: false,
    message: null,
  },
};
// 불러오기
export const __getPosts = createAsyncThunk(
  "GET_POSTS",
  async (payload, thunkAPI) => {
    try {
      // 데이터값 바로준다.
      const response = await postsAPI.get("/posts");
      return thunkAPI.fulfillWithValue(response);
    } catch (error) {
      console.log(error);
      return thunkAPI.rejectWithValue(error);
    }
  }
);

// 추가시

export const __addPost = createAsyncThunk(
  "ADD_POST",
  async (payload, thunkAPI) => {
    try {
      // 추가 하면 json에 추가되어 id값이 생성된, 등록한 객체 반환해줌
      const newPost = await postsAPI.post("/posts", payload);
      // 강의 보니까 그냥return 으로 처리해주는데
      //return newPost
      return thunkAPI.fulfillWithValue(newPost);
    } catch (error) {
      console.log("여기서 401이 잡여야함", error);

      //에러 핸들링 할 때는 별도의 예외처리가 필요한데, 표시(꼬리표)가 필요한데, 이 얘가 에러입니다. 라는 것이 필요한데, 그러므로 rejectWithValue를 '반드시' 넣어줘야한다.
      return thunkAPI.rejectWithValue(error);
    }
  }
);

// 편집하기
export const __editPost = createAsyncThunk(
  "EDIT_POST",
  async (payload, thunkAPI) => {
    try {
      // content만 수정해주기
      await postsAPI.patch(`/posts/${payload.id}`, {
        content: payload.editPost,
      });
      return thunkAPI.fulfillWithValue(payload);
    } catch (error) {
      console.log("editpsot", error);
      return thunkAPI.rejectWithValue(error);
    }
  }
);

// 삭제하기
export const __deletePost = createAsyncThunk(
  "DELETE_POST",
  async (payload, thunkAPI) => {
    try {
      await postsAPI.delete(`/posts/${payload}`);
      return thunkAPI.fulfillWithValue();
    } catch (error) {
      return thunkAPI.rejectWithValue(error);
    }
  }
);
const posts = createSlice({
  name: "fanLetterData",
  initialState,
  extraReducers: {
    // getPost
    [__getPosts.pending]: (state) => {
      state.isLoading = true;
      state.error.isError = false;
      state.error.message = "";
      state.error.status = "";
    },
    [__getPosts.fulfilled]: (state, action) => {
      state.isLoading = false;
      state.error.isError = false;
      state.error.message = "";
      state.error.status = "";
      state.posts = action.payload;
    },
    [__getPosts.rejected]: (state, action) => {
      state.isLoading = false;
      state.error.isError = true;
      state.error.message = action.payload.message;
      state.error.status = action.payload.status;
    },

    // Add_Post
    [__addPost.pending]: (state) => {
      state.isLoading = true;
      state.error.isError = false;
      state.error.message = "";
      state.error.status = "";
    },
    [__addPost.fulfilled]: (state, action) => {
      state.isLoading = false;
      state.error.isError = false;
      state.error.message = "";
      state.error.status = "";
      state.posts.push(action.payload);
    },
    [__addPost.rejected]: (state, action) => {
      state.isLoading = false;
      state.error.isError = true;
      state.error.message = action.payload.message;
      state.error.status = action.payload.status;
    },

    // EditPost
    [__editPost.pending]: (state) => {
      state.isLoading = true;
      state.error.isError = false;
      state.error.message = "";
      state.error.status = "";
    },
    [__editPost.fulfilled]: (state, action) => {
      state.isLoading = false;
      const targetIndex = state.posts.findIndex(
        (target) => target.id === parseInt(action.payload.id)
      );
      console.log("여기까지오냐???????????");
      state.posts[targetIndex].content = action.payload.editPost;
    },
    [__editPost.rejected]: (state, action) => {
      state.isLoading = false;
      state.error.isError = true;
      state.error.message = action.payload.message;
      state.error.status = action.payload.status;
    },

    // DELETE_POST
    [__deletePost.pending]: (state) => {
      state.isLoading = true;
      state.error.isError = false;
      state.error.message = "";
      state.error.status = "";
    },
    [__deletePost.fulfilled]: (state) => {
      state.isLoading = false;
    },
    [__deletePost.rejected]: (state, action) => {
      state.isLoading = false;
      state.error.isError = true;
      state.error.message = action.payload.message;
      state.error.status = action.payload.status;
    },
  },
});

export default posts.reducer;

reduxToolkit이랑 다른점은

export const{addPost,deletePost,editPost} = posts.actions

를 안해준다

0개의 댓글