Thunk 액션 생성자를 이용한, 비동기 함수의 사용 ( fetch ) 는, 다름이 아니라,
코드의 가독성과 컴포넌트 Fat 을 피하기 위한 한가지 방법일 뿐, 필수가 아니라는 사실을 생각하자.
필요에 의해, 함수 내에, fetch 함수를 바로 사용해도, 문제는 없다.
다만, 컴포넌트 Fat 은 보기에 불편하므로, Thunk 액션생성자를 사용하여, 비동기함수를 실행할 것이다.
1. store 안의 action 을 분리한다.
Slice 안에는, State 를 조작하는 기본 Slice.reducer 와 Slice.actions이 export 되고
actions 안에는 비동기 함수, 사이드이펙트 함수 가 정의되어 export 된다.
* Slice (Redux) 안의, 리듀서함수(state, action 담당) 에는, "순수함수" 만이 들어갈 수 있음을 인지하자
[Slice]
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
allQuotes: [],
};
const quotesSlice = createSlice({
name: "quotes",
initialState,
reducers: {
addQuotes(state, action) {
state.allQuotes.push(action.payload.quotes); // quotes 는 id, content, auythor 이 있는 객체
},
replaceQuotes(state, action) {
state.allQuotes = action.payload;
},
},
});
export const quotesActions = quotesSlice.actions;
export default quotesSlice.reducer;
[ Actions ] - 비동기 함수를 위한, Thunk 액션생성자
import { quotesActions } from "./quotes-slice";
import { uiActions } from "./ui-slice";
export const getQuotesData = () => { // [ 일반함수 ] 정의
return async (dispatch) => { // [함수 반환] dispatch 파라미터를 사용한,
dispatch(uiActions.fetchLoading(true)); // [로딩]시작하면 로딩
const fetchData = async () => { // [ 비동기 함수(fetch) 정의]
const response = await fetch(
"https://react-router-project-41a4b-default-rtdb.firebaseio.com/Quotes.json"
);
const responseData = await response.json();
const refinedData = []; // 파이어베이스 에서 오는 것 재정리
for (const key in responseData) {
refinedData.push({
id: responseData[key].id,
content: responseData[key].content,
author: responseData[key].author,
});
}
return refinedData;
};
const allQuotes = await fetchData(); // [ 비동기 함수(fetch) 실행]
dispatch(uiActions.fetchLoading(false)); // [로딩]끝나면 로딩 끝
dispatch(quotesActions.replaceQuotes(allQuotes)); // [결과값 State 에 입력]
};
};
2. 원하는 곳에 가서 사용한다.
이 함수는 모든 DB 데이터를 가져오는 함수이고,
all-quotes(모든 데이터) 를 보여주는, 컴포넌트가 있으므로, 그곳에서 사용하도록 하였다.
< AllQuotes Component>
import AllQuotesComponent from "../components/quotes/all-quotes";
import { useDispatch, useSelector } from "react-redux";
import { getQuotesData } from "../store/quotes-actions";
import { useEffect } from "react";
const AllQuotes = () => {
const uiState = useSelector((state) => state.uiSlice.getFetchLoading); // uiState를 가져온다
const dispatch = useDispatch();
useEffect(() => {
dispatch(getQuotesData()); // dispatch 를 통해, 실행한다 **
}, [dispatch]);
if (uiState) {
return <p> loading</p>; // uiState 가 true 면 Loading 이 나오게한다.
} // [후에, 다른 컴포넌트나, 로딩스피너, CSS 다 적용시켜서도 가능]
return (
<div>
<h1>명언들</h1>
<main>
<AllQuotesComponent />
</main>
</div>
);
};
export default AllQuotes;
'Redux, Redux-toolkit' 카테고리의 다른 글
10. [ Redux-toolkit ] createSelector !! memoization된 값을 반환한다 (0) | 2023.01.25 |
---|---|
9. State 를 빼왔다면, 따로 변수에 저장해 사용하는 것이 좋아 보인다. (0) | 2022.12.22 |
7. Redux-ToolKit [ 비동기, 사이드 이펙트 있는 함수 다루기 e.g. fetch함수] with useEffect ** (0) | 2022.12.17 |
6. Redux-ToolKit [ State 다루는 몇가지 팁들 ] (0) | 2022.12.17 |
5. Redux-ToolKit [ Slice 분할하기 ] (0) | 2022.12.17 |
댓글