Custom useFetch Hook으로 데이터 fetch하기

K·2022년 4월 5일

📚React & Redux

목록 보기
3/4
post-thumbnail

custom Hook을 통해 데이터를 fetch하는 연습을 해보았다.

먼저, api를 가져올 때 사용할 axios 패키지를 설치해준다.

✨yarn add axios 또는 npm install axios

그 다음, useEffect와 useState를 활용하는 useFetch hook을 만들었다.
여기서 관리할 state는 크게 3가지라 할 수 있다.
1. data
2. loading
3. error

따라서, 각 state별로 useState hook을 사용하고
useEffect의 의존성 배열에는 url을 넣어, url이 호출됐을 때만
axios와 setLoading이 작동하도록 한다.

// useFetch.js
import { useEffect, useState } from "react";
import axios from "axios";

function useFetch(url) {
  //null설정한 이유: 모든 data가 같진 않기 때문
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  useEffect(() => {
    setLoading(true);
    axios
      .get(url)
      .then((response) => {
        setData(response.data);
      })
      .catch((err) => {
        setError(err);
      })
      .finally(() => {
        setLoading(false);
      });
  }, [url]);

  return { data, loading, error };
}

export default useFetch;

이렇게 만든 useFetch hook은 App.js에서 쉽게 사용할 수 있다.

// App.js
import useFetch from "./useFetch";

function App() {
  const { data, loading, error } = useFetch("https://v2.jokeapi.dev/joke/Any");

  if (loading) return <h1>LOADING...</h1>;

  if (error) console.log(error);
  return (
    <di v className="App">
      <h1>
        {data?.setup} : {data?.delivery}
      </h1>
    </di>
  );
}

export default App;

++) refetch라는 함수를 useFetch에 추가해보자.

// useFetch.js
import { useEffect, useState } from "react";
import axios from "axios";

function useFetch(url) {
  //null설정한 이유: 모든 data가 같진 않기 때문
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  useEffect(() => {
    setLoading(true);
    axios
      .get(url)
      .then((response) => {
        setData(response.data);
      })
      .catch((err) => {
        setError(err);
      })
      .finally(() => {
        setLoading(false);
      });
  }, [url]);

  const refetch = () => {
    setLoading(true);
    axios
      .get(url)
      .then((response) => {
        setData(response.data);
      })
      .catch((err) => {
        setError(err);
      })
      .finally(() => {
        setLoading(false);
      });
  };

  return { data, loading, error, refetch };
}
export default useFetch;

refetch 버튼을 추가해,onClick될 때마다 refetch함수를 실행시키도록 해보자.

//App.js
import useFetch from "./useFetch";

function App() {
  const { data, loading, error, refetch } = useFetch(
    "https://v2.jokeapi.dev/joke/Any"
  );

  if (loading) return <h1>LOADING...</h1>;

  if (error) console.log(error);
  return (
    <di v className="App">
      <h1>
        {data?.setup} : {data?.delivery}
      </h1>

      <button onClick={refetch}>refetch</button>
    </di>
  );
}

export default App;

refetch버튼을 누를 때마다, 렌더링이 다시 일어나는 것을 볼 수 있다.
custom hook을 적절히 활용하면, 코드 가독성을 높이고 불필요한 코드를 줄일 수 있다는 것을 알게 되었다.

1개의 댓글

comment-user-thumbnail
2024년 3월 29일

refetch를 useCallback으로 묶기
useEffect 내부에서 refetch 호출하기

이러면 코드가 좀 더 깔끔해질 것 같습니다!

답글 달기