번역 자료 / / 2025. 5. 26. 17:56

[react 번역] cache

출처: https://react.dev/reference/react/cache


개요

cache는 React Server Components(서버 컴포넌트)에서만 사용할 수 있는 API로, 데이터 패칭이나 연산 결과를 캐싱(메모이제이션)할 수 있게 해줍니다. 동일한 인자로 호출 시 중복 연산을 방지하고, 여러 컴포넌트 간에 결과를 공유할 수 있습니다.

const cachedFn = cache(fn);

Reference

cache(fn)

컴포넌트 외부에서 cache를 호출해, 주어진 함수의 결과를 캐싱하는 버전을 만듭니다.

  • 파라미터
    • fn: 캐싱할 함수. 어떤 인자든 받을 수 있으며, 반환값도 자유롭습니다.
  • 반환값
    • 동일한 시그니처의 캐싱된 함수. 인자 조합별로 결과를 저장하며, 캐시 미스 시에만 원본 함수를 호출합니다.

동작 방식

  • 캐싱된 함수(cachedFn)를 호출하면, 동일한 인자로 이미 호출된 적이 있다면 캐시된 결과를 반환합니다. 없으면 원본 함수를 호출해 결과를 캐시에 저장 후 반환합니다.
  • 에러도 캐싱됩니다. 특정 인자에서 에러가 발생하면, 같은 인자로 호출 시 동일한 에러가 재발생합니다.
  • 각 서버 요청마다 캐시가 무효화됩니다(요청 단위 캐시).
  • 같은 함수로 여러 번 cache를 호출하면, 각각 별도의 캐시를 가집니다.
  • 반드시 컴포넌트 외부(모듈 스코프)에서 캐싱 함수를 생성해야 여러 컴포넌트에서 캐시를 공유할 수 있습니다.

Caveats(주의사항)

  • Server Components에서만 사용해야 하며, 클라이언트 컴포넌트에서는 동작하지 않습니다.
  • 캐싱된 함수는 인자 참조(객체, 배열 등)에 따라 캐시 히트 여부가 달라집니다. 동일한 값이라도 참조가 다르면 캐시 미스가 발생합니다.

사용법

고비용 연산 캐싱

import { cache } from 'react';
import calculateUserMetrics from 'lib/user';

const getUserMetrics = cache(calculateUserMetrics);

function Profile({ user }) {
  const metrics = getUserMetrics(user);
  // ...
}

function TeamReport({ users }) {
  for (let user of users) {
    const metrics = getUserMetrics(user);
    // ...
  }
}
  • 동일한 user 객체라면 여러 컴포넌트에서 연산 결과를 공유합니다.

데이터 스냅샷 공유

import { cache } from 'react';

async function fetchData() {
  return await fetch('https://...');
}

const getData = cache(fetchData);

async function MyComponent() {
  getData(); // 첫 호출: fetch 시작, 프라미스 캐싱
  // ...
  await getData(); // 두 번째 호출: 캐시된 프라미스 사용
}
  • 첫 호출에서 프라미스가 캐싱되고, 두 번째 호출에서는 같은 프라미스를 재사용합니다.

여러 컴포넌트에서 캐시 공유하기

  • 반드시 모듈 스코프에서 캐싱된 함수를 만들어 여러 컴포넌트에서 import해 사용해야 캐시가 공유됩니다.
// getWeekReport.js
import { cache } from 'react';
import { calculateWeekReport } from './report';
export default cache(calculateWeekReport);

// Temperature.js
import getWeekReport from './getWeekReport';
export default function Temperature({ cityData }) {
  const report = getWeekReport(cityData);
  // ...
}

// Precipitation.js
import getWeekReport from './getWeekReport';
export default function Precipitation({ cityData }) {
  const report = getWeekReport(cityData);
  // ...
}

Pitfall & 트러블슈팅

1. 서로 다른 캐싱 함수는 캐시를 공유하지 않음

  • 같은 원본 함수라도 여러 번 cache를 호출하면 각각 별도의 캐시를 가집니다. 반드시 하나의 캐싱 함수를 여러 컴포넌트에서 import해 사용하세요.

2. 컴포넌트 내부에서 cache 호출 시 캐시 공유 불가

  • 컴포넌트 내부에서 cache를 호출하면, 렌더마다 새로운 캐싱 함수가 생성되어 캐시가 공유되지 않습니다.

3. 객체/배열 등 참조값 인자 주의

  • 인자가 객체/배열 등 참조 타입이면, 값이 같아도 참조가 다르면 캐시 미스가 발생합니다. 원시값(primitive) 인자를 사용하거나, 동일한 참조를 전달해야 합니다.
// 잘못된 예시
const calculateNorm = cache((vector) => { /* ... */ });
function MapMarker(props) {
  const length = calculateNorm(props); // props는 매번 새 객체
}

// 올바른 예시
const calculateNorm = cache((x, y, z) => { /* ... */ });
function MapMarker(props) {
  const length = calculateNorm(props.x, props.y, props.z); // 원시값 사용
}

useMemo, memo, cache 차이

  • useMemo: 클라이언트 컴포넌트에서 렌더 간 동일한 연산을 캐싱(컴포넌트 인스턴스 단위, 공유 불가)
  • memo: props가 바뀌지 않으면 컴포넌트 자체의 리렌더를 막음(컴포넌트 단위)
  • cache: 서버 컴포넌트에서 여러 컴포넌트 간 연산/패칭 결과를 공유(요청 단위, 모듈 단위로 공유)

참고 및 주의사항

  • cache는 반드시 Server Components에서만 사용해야 하며, 클라이언트 컴포넌트에서는 동작하지 않습니다.
  • 캐싱된 함수는 인자 참조에 민감하므로, 동일한 참조를 전달하거나 원시값을 사용하는 것이 좋습니다.
  • 각 서버 요청마다 캐시가 초기화됩니다.

출처: https://react.dev/reference/react/cache

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유