2 분 소요


React Query와 같은 라이브러리를 사용하면 데이터 패칭, 캐싱, 동기화 및 에러 처리를 훨씬 더 쉽게 관리할 수 있으니 추후 공부하도록 하자!


1. 로딩 상태와 에러 처리

로딩 상태와 에러 상태를 별도의 state로 관리하여 더 명확하게 로딩 중 메시지와 에러 메시지를 표시할 수 있다.

import { useEffect, useState } from "react";
import axios from "axios";

const MainPage = () => {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(true); // 처음에 들어오면 로딩 활성화
  const [error, setError] = useState(null); /// 에러를 저장

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await axios.get(
          "https://jsonplaceholder.typicode.com/posts"
        );
        setData(response.data);
      } catch (error) {
        setError(error);
      } finally {
        setLoading(false); // 데이터 요청 완료 후 로딩 상태 업데이트
      }
    };

    fetchData();
  }, []);

  if (loading) {
    return <div>로딩중...</div>;
  }

  if (error) {
    return <div>Error: {error.message}</div>;
  }

  return (
    <div>
      {data.length > 0 ? (
        <>
          {data.map((data) => (
            <div key={data.id}>{data.title}</div>
          ))}
        </>
      ) : (
        <div>No Data Available</div>
      )}
    </div>
  );
};

export default MainPage;



2. 로딩 스피너 사용하기

로딩 중 메시지 대신 react-spinners와 같은 라이브러리를 사용하여 쉽게 로딩 스피너를 추가할 수 있다.

먼저, react-spinners 라이브러리를 설치하자

yarn add react-spinners


그런 다음, 로딩 스피너를 사용하여 로딩 중 상태를 표시하자.

import { useEffect, useState } from "react";
import { ClipLoader } from "react-spinners";
import axios from "axios";

const MainPage = () => {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await axios.get(
          "https://jsonplaceholder.typicode.com/posts"
        );

        if (!response || !response.data) {
          throw new Error("Data not found");
        }

        setData(response.data);
      } catch (error) {
        setError(error);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, []);

  if (loading) {
    return (
      <div className="loading-container">
        <ClipLoader size={150} />
      </div>
    );
  }

  if (error) {
    return <div>Error: {error.message}</div>;
  }

  return (
    <div className="main-container">
      {data.length > 0 ? (
        data.map((item) => (
          <div key={item.id} className="item">
            {item.title}
          </div>
        ))
      ) : (
        <div>No Data Available</div>
      )}
    </div>
  );
};

export default MainPage;



3. 재시도 버튼 추가하기

네트워크 요청이 실패했을 때 사용자가 요청을 다시 시도할 수 있도록 재시도 버튼을 추가할 수 있다.

import React, { useEffect, useState } from "react";

const MainPage = () => {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  const fetchData = async () => {
    setLoading(true);
    setError(null);

    try {
      const response = await fetch(
        "https://jsonplaceholder.typicode.com/posts"
      );

      if (!response.ok) {
        throw new Error("Network response was not ok");
      }

      const data = await response.json();
      setData(data);
    } catch (error) {
      setError(error);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchData();
  }, []);

  if (loading) {
    return <div>로딩중,..</div>;
  }

  if (error) {
    return (
      <div>
        Error: {error.message}
        <button onClick={fetchData}>재시도</button>
      </div>
    );
  }

  return (
    <div>
      {data.length > 0 ? (
        <>
          {data.map((item) => (
            <div key={item.id}>{item.title}</div>
          ))}
        </>
      ) : (
        <div>No Data Available</div>
      )}
    </div>
  );
};

export default MainPage;


카테고리:

업데이트:

댓글남기기