본문 바로가기
React

React에서 로딩 상태 관리하기

by 굿센스굿 2024. 12. 11.
반응형

 

웹 애플리케이션에서 로딩 상태 관리는 사용자 경험(UX)을 결정짓는 중요한 요소 중 하나입니다. 비동기 작업(예: API 호출, 데이터 로딩, 이미지 업로드 등)이 수행될 때 사용자에게 진행 상황을 명확히 전달하지 않으면 혼란을 줄 수 있습니다. 이번 글에서는 React에서 로딩 상태를 효과적으로 관리하는 방법을 살펴보고, 다양한 접근 방식과 최적화 팁을 제시하겠습니다.


1. 로딩 상태 관리의 중요성

사용자 경험에서 로딩 상태를 잘 관리하면 다음과 같은 이점을 얻을 수 있습니다.

  1. 직관적인 피드백 제공
    로딩 상태를 명확히 표시하면 사용자는 현재 작업이 진행 중임을 알 수 있습니다.
  2. 이탈률 감소
    작업 상태가 불확실하면 사용자가 애플리케이션을 떠날 가능성이 높아집니다. 로딩 스피너나 메시지는 사용자 충성도를 높이는 데 기여합니다.
  3. 애플리케이션 신뢰도 향상
    비동기 작업이 완료되지 않았음을 알리고, 완료 시점에 적절히 응답하면 신뢰감을 줄 수 있습니다.

2. React에서 로딩 상태를 관리하는 기본 패턴

1) 로컬 상태 관리 (useState)

로딩 상태를 단순히 useState를 활용해 관리할 수 있습니다.

import React, { useState } from 'react';

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

  const fetchData = async () => {
    setLoading(true);
    setError(null);
    try {
      const response = await fetch('https://api.example.com/data');
      const result = await response.json();
      setData(result);
    } catch (err) {
      setError('데이터를 가져오는 중 오류가 발생했습니다.');
    } finally {
      setLoading(false);
    }
  };

  return (
{loading &&

로딩 중...

} {error &&

{error}

} {data &&
{JSON.stringify(data, null, 2)}
}
); }; export default FetchData;

설명:

  1. loading 상태는 데이터 요청이 진행 중일 때 true로 설정됩니다.
  2. 요청 완료 후 finally 블록에서 loading을 다시 false로 설정합니다.
  3. 로딩 상태에 따라 사용자에게 적절한 UI를 제공합니다.

2) 글로벌 상태 관리 (Context API)

여러 컴포넌트에서 로딩 상태를 공유해야 하는 경우, Context API를 사용해 상태를 관리할 수 있습니다.

import React, { createContext, useState, useContext } from 'react';

const LoadingContext = createContext();

const LoadingProvider = ({ children }) => {
  const [loading, setLoading] = useState(false);

  return (
    <LoadingContext.Provider value={{ loading, setLoading }}>
      {children}
    </LoadingContext.Provider>
  );
};

const useLoading = () => useContext(LoadingContext);

const Loader = () => {
  const { loading } = useLoading();
  return loading ? <p>로딩 중...</p> : null;
};

const FetchDataWithContext = () => {
  const { setLoading } = useLoading();

  const fetchData = async () => {
    setLoading(true);
    try {
      await new Promise((resolve) => setTimeout(resolve, 2000)); // 모의 비동기 작업
    } finally {
      setLoading(false);
    }
  };

  return <button onClick={fetchData}>데이터 가져오기</button>;
};

const App = () => (
  <LoadingProvider>
    <Loader />
    <FetchDataWithContext />
  </LoadingProvider>
);

export default App;

설명:

  1. LoadingContext를 통해 로딩 상태를 전역으로 관리합니다.
  2. Loader 컴포넌트는 loading 상태를 구독하여 전역적으로 로딩 UI를 렌더링합니다.

3. 고급 로딩 상태 관리 방법

1) React Query 사용

React Query는 비동기 데이터 요청을 관리하기 위한 강력한 라이브러리로, 로딩 상태를 자동으로 관리합니다.

import { useQuery } from 'react-query';

const FetchDataWithReactQuery = () => {
  const { data, isLoading, error } = useQuery('fetchData', async () => {
    const response = await fetch('https://api.example.com/data');
    return response.json();
  });

  if (isLoading) return

로딩 중...

;
  if (error) return

오류가 발생했습니다: {error.message}

;

  return
{JSON.stringify(data, null, 2)}
; }; export default FetchDataWithReactQuery;

설명:

  1. useQuery 훅은 데이터 요청 상태(isLoading, error, data)를 자동으로 관리합니다.
  2. 코드 양이 줄어들고 로딩 상태 관리가 간편해집니다.

2) Suspense와 React.lazy

React의 Suspense를 활용해 비동기 컴포넌트 로딩 상태를 관리할 수 있습니다.

import React, { Suspense } from 'react';

const LazyComponent = React.lazy(() => import('./SomeComponent'));

const App = () => (
  <Suspense fallback={<p>로딩 중...</p>}>
    <LazyComponent />
  </Suspense>
);

export default App;

설명:

  1. React.lazy는 동적 import로 컴포넌트를 지연 로드합니다.
  2. Suspense는 로딩 중일 때 보여줄 UI를 지정합니다.

4. 로딩 상태 최적화 팁

  1. 스켈레톤 UI 활용
    데이터를 기다리는 동안 빈 콘텐츠를 보여주는 대신, 데이터를 로드하기 전 모습을 모방한 스켈레톤 UI를 표시해 자연스러운 UX를 제공합니다.
  2. Debouncing 로딩 상태
    짧은 작업에 대해 로딩 UI를 표시하지 않도록 디바운스를 적용합니다.
  3. 로딩 상태 분리
    비동기 작업이 여러 개일 경우, 각 작업의 로딩 상태를 독립적으로 관리합니다.

결론

React에서 로딩 상태를 관리하는 방법은 프로젝트 규모와 요구 사항에 따라 다양하게 선택할 수 있습니다. 단순한 로컬 상태 관리부터 Context API, React Query와 같은 외부 라이브러리까지, 각각의 도구는 특정 시나리오에 적합한 해법을 제공합니다. 로딩 상태를 명확히 관리하고 사용자 경험을 개선하는 데 이번 글이 도움이 되길 바랍니다.

Happy Coding! 🚀

반응형