frontend/react

[React] React.js 강좌 18. 대시보드 구현 – React Query로 사용자 데이터 효율적으로 불러오기

mirabo01 2025. 11. 10. 08:53

1. 로그인 후 보여지는 대시보드란?

로그인 시스템을 구축했다면,
다음 단계는 **로그인한 사용자의 데이터를 시각적으로 보여주는 대시보드(Dashboard)**입니다.

예를 들어 다음과 같은 정보가 표시됩니다.

  • 로그인한 사용자의 이름, 이메일, 가입일
  • 최근 활동 내역
  • 알림, 메시지, 통계 등

이 페이지는 서버에서 **로그인된 사용자 정보(API)**를 가져와야 하며,
데이터 갱신이 잦기 때문에 React Query를 사용하는 것이 가장 효율적입니다.


2. 기본 구조

대시보드 페이지를 구현하기 위해 다음 세 가지가 필요합니다.

1️⃣ 사용자 인증 토큰을 포함한 API 요청
2️⃣ React Query의 useQuery로 데이터 가져오기
3️⃣ 로딩/에러/성공 상태에 따른 UI 처리


3. API 요청 설정

Axios를 사용할 때,
모든 요청에 인증 토큰을 자동으로 포함시키면 편리합니다.

// api.js
import axios from 'axios';

const api = axios.create({
  baseURL: '/api',
});

api.interceptors.request.use((config) => {
  const token = localStorage.getItem('accessToken');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

export default api;

이제 api.get()을 호출하면
자동으로 Authorization 헤더가 포함됩니다.


4. React Query로 사용자 데이터 가져오기

import { useQuery } from '@tanstack/react-query';
import api from './api';

function Dashboard() {
  const { data, isLoading, isError, refetch } = useQuery({
    queryKey: ['userProfile'],
    queryFn: async () => {
      const res = await api.get('/me');
      return res.data;
    },
  });

  if (isLoading) return <p>로딩 중입니다...</p>;
  if (isError) return <p style={{ color: 'red' }}>데이터를 불러오지 못했습니다.</p>;

  const { name, email, createdAt, recentActivity } = data.user;

  return (
    <div style={{ padding: '20px' }}>
      <h2>대시보드</h2>
      <div style={{ marginBottom: '20px' }}>
        <h3>👋 {name}님 환영합니다.</h3>
        <p>이메일: {email}</p>
        <p>가입일: {new Date(createdAt).toLocaleDateString()}</p>
      </div>

      <section>
        <h3>최근 활동</h3>
        {recentActivity.length === 0 ? (
          <p>최근 활동 내역이 없습니다.</p>
        ) : (
          <ul>
            {recentActivity.map((act, i) => (
              <li key={i}>{act}</li>
            ))}
          </ul>
        )}
      </section>

      <button onClick={() => refetch()} style={{ marginTop: '20px' }}>
        데이터 새로고침
      </button>
    </div>
  );
}

export default Dashboard;

작동 설명

  • queryKey: 데이터를 구분하는 식별자 (['userProfile'])
  • queryFn: 실제 API 호출 함수
  • refetch: 버튼 클릭 시 데이터 강제 갱신

5. 데이터 갱신과 자동 리페칭

React Query는 다음과 같은 상황에서 데이터를 자동으로 리페칭(refetch) 합니다.

  • 브라우저가 다시 포커스될 때
  • 네트워크 연결이 복구될 때
  • invalidateQueries()가 호출될 때

예를 들어 로그인 후 사용자 정보를 최신으로 유지하고 싶다면,
로그인 성공 시 다음을 실행하면 됩니다.

queryClient.invalidateQueries(['userProfile']);

이렇게 하면 React Query가 자동으로 /api/me를 다시 호출합니다.


6. 로딩 상태 개선 (Skeleton UI)

로딩 중일 때 단순히 “로딩 중입니다”라는 문구 대신
Skeleton UI를 보여주면 사용자 경험이 훨씬 좋아집니다.

function LoadingSkeleton() {
  return (
    <div style={{ padding: '20px', opacity: 0.6 }}>
      <div style={{ background: '#ddd', height: '20px', width: '40%', marginBottom: '10px' }} />
      <div style={{ background: '#ddd', height: '15px', width: '60%', marginBottom: '10px' }} />
      <div style={{ background: '#ddd', height: '15px', width: '80%', marginBottom: '10px' }} />
    </div>
  );
}
if (isLoading) return <LoadingSkeleton />;

이렇게 하면 데이터 로딩 중에도 깔끔한 UI 유지가 가능합니다.


7. React Query Devtools로 상태 확인

React Query의 캐시, 로딩 상태, 쿼리 갱신 현황을 시각적으로 확인하려면
Devtools를 추가하면 됩니다.

npm install @tanstack/react-query-devtools
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';

<QueryClientProvider client={client}>
  <App />
  <ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>

이제 브라우저에서 쿼리 상태를 실시간으로 확인할 수 있습니다.


8. React Query 캐시 활용

React Query는 데이터를 자동으로 캐싱합니다.
즉, 사용자가 페이지를 다시 방문하더라도
staleTime 내에서는 네트워크 요청 없이 기존 데이터를 사용합니다.

useQuery({
  queryKey: ['userProfile'],
  queryFn: fetchUser,
  staleTime: 1000 * 60 * 5, // 5분 동안 캐시 유지
});

이는 특히 대시보드처럼 자주 접근하는 페이지에서 매우 효과적입니다.


9. 에러 처리 전략

API 요청 중 오류가 발생할 경우를 대비해
서버 메시지를 그대로 보여주는 것이 좋습니다.

if (isError) {
  return (
    <div style={{ color: 'red' }}>
      서버 오류가 발생했습니다.<br />
      관리자에게 문의해주세요.
    </div>
  );
}

또는 React Query의 onError 콜백을 이용해
전역 에러 핸들러를 구성할 수도 있습니다.

const client = new QueryClient({
  defaultOptions: {
    queries: {
      onError: (err) => console.error('쿼리 에러:', err),
    },
  },
});

10. 마무리

이번 강의에서는 로그인 이후 보여지는 사용자 대시보드
React Query를 이용해 구현했습니다.

핵심 요약:

  • Axios Interceptor로 토큰 자동 처리
  • useQuery로 사용자 정보 불러오기
  • 자동 리페칭과 캐시를 활용한 효율적 데이터 관리
  • Skeleton UI로 UX 향상

React Query를 이용하면 서버와의 데이터 동기화를 직접 관리하지 않아도 되므로,
복잡한 상태 관리 없이도 최신 데이터를 유지하는 안정적인 대시보드를 만들 수 있습니다.

다음 강의에서는 React Router를 활용한 다중 페이지 대시보드 구조를 만들고,
라우트 간 데이터 캐싱과 전환 최적화 방법을 알아보겠습니다.