250x250
반응형
arkhyeon
arkhyeon
arkhyeon
전체 방문자
오늘
어제
  • 분류 전체보기 (88)
    • Spring (5)
    • Java (4)
    • React (25)
      • TypeScript (6)
      • JavaScript (1)
      • Jest (9)
    • NEXT (8)
    • SQL (1)
    • React native (1)
    • CSS (3)
    • Web (1)
    • Git (3)
    • ETC (6)
    • 빅데이터DB (8)
    • Docker (4)
    • Tool (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • react typescript
  • HIVE
  • WSS
  • jest
  • react loading
  • usetransition
  • docker tomcat
  • websocket
  • node WebSocket
  • websocket server
  • react19
  • react
  • react usetransition
  • react jest
  • react spring websocket
  • javasciprt websocket
  • react websocket
  • kudu
  • Spring WebSocket
  • javascript wss

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
arkhyeon

arkhyeon

React

React 19 Data Caching (map, React Query, swr)

2025. 1. 13. 09:41
728x90
반응형

Map 객체를 활용한 데이터 캐싱

요청했던 URL과 데이터를 Map에 저장하므로 동일한 요청은 서버에 다시 호출하지 않고, 저장된 데이터를 반환합니다.

data.js

import { axios } from "./axios.js";

let cache = new Map();

export function fetchData(url) {
  if (!cache.has(url)) {
    cache.set(url, getData(url));
  }
  return cache.get(url);
}

async function getData(url) {
  if (url.startsWith("/search?q=")) {
    return await getSearchResults(url.slice("/search?q=".length));
  } else {
    throw Error("Not implemented");
  }
}
async function getSearchResults(query) {
  // Add a fake delay to make waiting noticeable.
  await new Promise((resolve) => {
    setTimeout(resolve, 500);
  });
  const a = await axios.get(`/departments/${query}`);

  return a.data.departments;
}
  • 캐시가 Map에 무한정 쌓이고 오래된 데이터가 계속 유지될 수 있습니다.
  • 현재 캐시는 해당 컴포넌트 내에서만 사용됩니다. 여러 컴포넌트에서 캐시를 유지하려면 context나 전역 상태 관리 라이브러리가 필요합니다.

React Query

복잡한 데이터 흐름과 상태 관리가 필요한 대규모 프로젝트 용이

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

const fetchDepartments = async (query) => {
  const response = await axios.get(`/departments/${query}`);
  return response.data.departments;
};

const DepartmentList = ({ query }) => {
  const { data, isLoading, error } = useQuery(
    ['departments', query],
    () => fetchDepartments(query),
    { staleTime: 300000 } // 캐시 데이터 유지 시간
  );

  if (isLoading) return <p>Loading...</p>;
  if (error) return <p>Error loading data</p>;

  return (
    <ul>
      {data.map((dept) => (
        <li key={dept.id}>{dept.name}</li>
      ))}
    </ul>
  );
};

export default DepartmentList;

SWR

소규모 프로젝트나 간단한 데이터 패칭만 필요한 경우 용이

import useSWR from 'swr';
import axios from 'axios';

const fetcher = (url) => axios.get(url).then((res) => res.data.departments);

const DepartmentList = ({ query }) => {
  const { data, error, isLoading } = useSWR(`/departments/${query}`, fetcher);

  if (isLoading) return <p>Loading...</p>;
  if (error) return <p>Error loading data</p>;

  return (
    <ul>
      {data.map((dept) => (
        <li key={dept.id}>{dept.name}</li>
      ))}
    </ul>
  );
};

export default DepartmentList;

 

여러가지 데이터 캐싱 방법이 있으니 용도에 맞춰 사용하시면 되겠습니다.

Layout

App.jsx

import { Suspense, useState} from "react";
import Department from "./Department.jsx";

function App() {
  const [id, setId] = useState(0);

  return (
    <div className="min-h-screen bg-gray-100 p-6">
      <input type="number" value={id} onChange={(e) => setId(Number(e.target.value))} />
      <Suspense fallback={<Loading />}>
        <div className="mb-6">
          <Department id={id} />
        </div>
      </Suspense>
    </div>
  );
}

export default App;

function Loading() {
  return <h2>🌀 Loading...</h2>;
}

Department.jsx

Department.jsx

//Department.jsx
import { use } from "react";
import { fetchData } from "./data.js";

function Department({ id }) {
  const department = use(fetchData(`/search?q=${id}`));

  if (id === 0) {
    return null;
  }

  return (
    <div>
      {department.map((dm) => (
        <div className="border border-gray-300 p-4 rounded-md" key={dm.departmentId} >
          <h2 className="text-xl font-bold mb-2">이름 : {dm.name}</h2>
          <p className="text-gray-600">ID: {dm.departmentId}</p>
          <p className="text-gray-600">설명: {dm.description}</p>
          <p className="text-gray-600">위치: {dm.location}</p>
        </div>
      ))}
    </div>
  );
}

export default Department;
728x90
반응형

'React' 카테고리의 다른 글

useDeferredValue 와 useTransition 차이  (0) 2025.01.13
React Suspense와 use로 빈 데이터 문제 해결하기  (0) 2025.01.10
React 19 useTransition을 활용한 Axios 데이터 로딩과 상태 업데이트  (0) 2025.01.10
React 19의 useTransition을 활용한 비동기 상태 업데이트와 UI 반응성 향상  (0) 2025.01.09
React 19 useTransition vs React 18 pending 처리 : 로딩 상태 관리의 차이점  (0) 2024.12.31
    'React' 카테고리의 다른 글
    • useDeferredValue 와 useTransition 차이
    • React Suspense와 use로 빈 데이터 문제 해결하기
    • React 19 useTransition을 활용한 Axios 데이터 로딩과 상태 업데이트
    • React 19의 useTransition을 활용한 비동기 상태 업데이트와 UI 반응성 향상
    arkhyeon
    arkhyeon

    티스토리툴바