// 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
를 안해준다