From a98e95cf7c468afe66ec54c152f4b409be39a1b1 Mon Sep 17 00:00:00 2001 From: jayjeong8 Date: Wed, 21 Dec 2022 17:41:32 +0900 Subject: [PATCH] =?UTF-8?q?refactor=20#202=20:=20=EC=98=81=EC=88=98?= =?UTF-8?q?=EC=A6=9D=20=EB=AA=85=EC=96=B8=20=EC=83=81=ED=83=9C=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=EB=A5=BC=20useReducer=EB=A5=BC=20=EC=9D=B4=EC=9A=A9?= =?UTF-8?q?=ED=95=9C=20=ED=9B=85=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 상태에 따라 나타나는 명언을 더 쉽게 컨트롤하기 위해 변경했습니다. --- .../atoms/ReceiptQuotes/ReceiptQuotes.jsx | 23 ++++---- src/hooks/useAsync.jsx | 54 +++++++++++++++++++ 2 files changed, 65 insertions(+), 12 deletions(-) create mode 100644 src/hooks/useAsync.jsx diff --git a/src/components/atoms/ReceiptQuotes/ReceiptQuotes.jsx b/src/components/atoms/ReceiptQuotes/ReceiptQuotes.jsx index 8ce7899..6db98da 100644 --- a/src/components/atoms/ReceiptQuotes/ReceiptQuotes.jsx +++ b/src/components/atoms/ReceiptQuotes/ReceiptQuotes.jsx @@ -1,5 +1,5 @@ -import { useEffect, useState } from "react"; import * as S from "./ReceiptQuotes.styles"; +import useAsync from "../../../hooks/useAsync"; /** * ReceiptQuotes @@ -10,18 +10,17 @@ import * as S from "./ReceiptQuotes.styles"; * @returns */ export function ReceiptQuotes() { - const [quotesState, setQuotes] = useState(); + const [state] = useAsync(getQuotes, []); + const { loading, data: quote, error } = state; + console.log(quote); - useEffect(() => { - const getQuotes = async () => { - await fetch("https://api.adviceslip.com/advice") - .then((response) => response.json()) - .then((data) => setQuotes(data.slip.advice)) - .catch((e) => console.error(e)); - }; + return {loading || error ? "Well done!" : quote}; +} - getQuotes(); - }, []); +async function getQuotes() { + const response = await fetch("https://api.adviceslip.com/advice").then((response) => + response.json(), + ); - return {quotesState || "Well done!"}; + return response.slip.advice; } diff --git a/src/hooks/useAsync.jsx b/src/hooks/useAsync.jsx new file mode 100644 index 0000000..e4be0c2 --- /dev/null +++ b/src/hooks/useAsync.jsx @@ -0,0 +1,54 @@ +// 참고 자료 - https://react.vlpt.us/integrate-api/03-useAsync.html + +import { useReducer, useEffect } from "react"; + +function reducer(state, action) { + switch (action.type) { + case "LOADING": + return { + loading: true, + data: null, + error: null, + }; + case "SUCCESS": + return { + loading: false, + data: action.data, + error: null, + }; + case "ERROR": + return { + loading: false, + data: null, + error: action.error, + }; + default: + throw new Error(`Unhandled action type: ${action.type}`); + } +} + +function useAsync(callback, deps = []) { + const [state, dispatch] = useReducer(reducer, { + loading: false, + data: null, + error: false, + }); + + const fetchData = async () => { + dispatch({ type: "LOADING" }); + try { + const data = await callback(); + dispatch({ type: "SUCCESS", data }); + } catch (e) { + dispatch({ type: "ERROR", error: e }); + } + }; + + useEffect(() => { + fetchData(); + }, deps); + + return [state, fetchData]; +} + +export default useAsync;