Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 파이썬 딕셔너리
- 타입스크립트 리액트
- 내일배움캠프 프로젝트
- 파이썬 for in
- typeScript
- Next 팀 프로젝트
- 리액트
- JavaScript
- 내일배움캠프
- React Hooks
- 타입스크립트
- 프로그래머스
- 내일배움캠프 최종 프로젝트
- 파이썬 replace
- 코딩테스트
- 내배캠 프로젝트
- 파이썬 for
- 리액트 훅
- 타입스크립트 props
- useState
- tanstack query
- 파이썬 enumerate
- 파이썬 반복문
- REACT
- 한글 공부 사이트
- 파이썬 list
- 자바스크립트
- js
- 파이썬 slice
- 리액트 프로젝트
Archives
- Today
- Total
sohyeon kim
[React] Redux Thunk App 본문
728x90
2024.02.19 - [React] - [React] Redux Thunk : 미들웨어
💡 thunk 함수를 한번 더 구현해보자!
- thunk 함수 구현
- 리듀서 로직 구현 : reducers ➡️ extraReducers
- 서버 통신 : 100% 성공 ❌ (불확실)
- 지금까지의 redux state - todos, counter
- 앞으로의 state - isLoading, is Error, Data
- 기능 확인 : network or devTools
- Store 의 값을 조회, 화면에 렌더링
db.json
{
"todos": [
{
"id": 1,
"title": "hello world!"
},
{
"id": 2,
"title": "hello react!"
}
]
}
todosSlice.js
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import axios from "axios";
const initialState = {
todos: [],
isLoading: false, // 세 state 값을 넣어줌
isError: false,
error: null,
};
export const __getTodos = createAsyncThunk(
"getTodos", // 이름
async (payload, thunkAPI) => { // 비동기 함수
try {
const response = await axios.get("http://localhost:4002/todos");
console.log("response", response);
} catch (error) {
console.log("error", error);
}
}
);
export const todosSlice = createSlice({
name: "todos",
initialState,
// reducers: {},
// extraReducers: {},
});
export const {} = todosSlice.actions;
export default todosSlice.reducer;
App.js
import "./App.css";
import { useEffect } from "react";
import { useDispatch } from "react-redux";
import { __getTodos } from "./modules/todosSlice";
function App() {
const dispatch = useDispatch();
useEffect(() => {
dispatch(__getTodos());
}, [dispatch]);
return (
<div>
<h2>Thunk App</h2>
</div>
);
}
export default App;
👀 서버의 데이터(json-server 이지만)를 잘 가져오고 있다!
🤤 그럼 이제 toolkit 에서 제공하는 API 를 이용해 가져온 데이터를 store 에 넣어보자.
thunkAPI.fulfillWithValue() - 성공 시 사용할 API
Promise ➡️ reslove(네트워크 요청 성공한 경우) dispatch 해주는 기능을 가진 API
thunkAPI.rejectWithValue() -오류 시 사용할 API
Promise ➡️ reject(네트워크 요청 실패한 경우) dispatch 해주는 기능을 가진 API
todosSlice.js
export const __getTodos = createAsyncThunk(
"getTodos",
async (payload, thunkAPI) => {
try {
const response = await axios.get("http://localhost:4002/todos"); // 여기서 오류가 나면 catch 로 간다.
return thunkAPI.fulfillWithValue(response.data); // response.data 를 들고 dispatch ~
} catch (error) {
return thunkAPI.rejectWithValue(error);
}
}
);
export const todosSlice = createSlice({
name: "todos",
initialState,
// reducers: {},
extraReducers: (builder) => { // dispatch 받아서 ~~
builder.addCase(__getTodos.pending, (state, action) => { // pending 으로 찾아감
console.log("pending", action);
});
builder.addCase(__getTodos.fulfilled, (state, action) => { // fulfilled 로 찾아감
console.log("fulfilled", action);
});
builder.addCase(__getTodos.rejected, (state, action) => { // rejected 로 찾아감
console.log("rejected", action);
});
},
});
제 기능을 하도록 바꿔보자!
export const todosSlice = createSlice({
name: "todos",
initialState,
// reducers: {},
extraReducers: (builder) => {
builder.addCase(__getTodos.pending, (state) => {
state.isLoading = true; // 가져오는(진행) 중이니 로딩이 true
state.isError = false; // 가져오는(진행) 중이니 에러가 false
});
builder.addCase(__getTodos.fulfilled, (state, action) => {
state.isLoading = false; // 성공한 상태이니 로딩이 false
state.isError = false; // 성공한 상태이니 에러가 false
state.todos = action.payload; // 성공했으니 state.todos 에 가져온 payload 를 넣는다.
});
builder.addCase(__getTodos.rejected, (state, action) => {
state.isLoading = false; // 실패한 상태이니 로딩이 false
state.isError = true; // 실패한 상태이니 에러가 true
state.error = action.payload; // 실패했으니 state.error 에 가져온 payload 를 넣는다.
});
},
});
App.jsx
import "./App.css";
import { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { __getTodos } from "./modules/todosSlice";
function App() {
const dispatch = useDispatch();
const { isLoading, error, todos } = useSelector((state) => state.todos);
useEffect(() => {
dispatch(__getTodos());
}, [dispatch]);
if (isLoading) { // 로딩 중이니 젤 위에 위치, 아래 로직이 읽힐(렌더링 될) 필요 없음
return <div>Loding...</div>;
}
if (error) { // 에러이니 아래 성공 로직이 읽힐(렌더링 될) 필요 없음
return <div>{error.message}</div>;
}
return (
<div>
<h2>Thunk App</h2>
{todos.map((todo) => {
return <h3 key={todo.id}>{todo.title}</h3>;
})}
</div>
);
}
export default App;
👀 로딩 화면이 잠깐 뜬 뒤, todos 를 잘 가져온 화면을 볼 수 있다!
728x90
반응형
'React' 카테고리의 다른 글
[React] Error : Cannot read properties of null (reading 'useMemo') (0) | 2024.02.20 |
---|---|
[React] Custom Hooks : 훅 만들기 (0) | 2024.02.20 |
[React] Redux Thunk : 미들웨어 (0) | 2024.02.19 |
[React] axios & interseptor : api 생성, URL 생략 & 요청, 응답 사이에 관여 (0) | 2024.02.19 |
[React] env : npm, vite 환경 변수 사용하기, 변수 숨기기 (0) | 2024.02.19 |