React

 

 

1.Next.js의 캐싱 메커니즘 요약

 

Next.js는 네 가지 주요 캐싱 메커니즘을 사용하여 성능을 최적화하고,

불필요한 데이터 요청을 줄입니다.

 

 

 

1) 요청 기억(Request Memorization)

  • 개념: 동일한 설정을 가진 데이터 요청을 저장하여 중복 요청을 방지.
  • 작동 방식: 단일 요청 동안 Next.js 서버가 동일한 데이터 소스에 대한 중복 요청을 피하기 위해 캐시를 유지.
  • 범위: 단일 요청 처리 동안에만 발생.
  • 목적: 데이터 소스에 대한 불필요한 중복 요청 방지.

 

 

2) 데이터 캐시(Data Cache)

  • 개념: 데이터 소스에서 변경되지 않은 경우 데이터를 저장하고 재사용.
  • 작동 방식: 데이터가 변경되지 않는 한, 데이터 요청을 완전히 피함으로써 성능을 향상.
  • 목적: 중복 요청을 줄이거나 방지하여 애플리케이션의 속도를 높임.
  • 지속성: 데이터가 변경되거나 수동으로 재검증할 때까지 지속.

 

 

 

3) 전체 라우트 캐시(Full Route Cache)

  • 개념: 전체 페이지, HTML 코드, React 서버 컴포넌트 페이로드를 캐시.
  • 작동 방식: 페이지를 다시 렌더링하지 않고 기존 페이지를 재사용하여 성능을 향상.
  • 목적: 추가적인 서버 왕복을 피하고 페이지 로딩 속도를 높임.
  • 지속성: 관련 데이터 캐시가 재검증될 때까지 지속, 업데이트된 데이터가 있을 때만 페이지가 다시 렌더링.

 

 

 

4) 라우터 캐시(Router Cache)

  • 개념: 클라이언트 측에서 관리되는 캐시로, 브라우저 메모리에 일부 React 서버 컴포넌트 페이로드를 저장.
  • 작동 방식: 페이지 간의 이동을 더 빠르게 하기 위해 클라이언트 측에서 페이지 데이터를 관리.
  • 목적: 페이지 이동 시 속도를 높이기 위해 서버 요청을 피하거나 최소화.
  • 지속성: 서버에서 새로운 페이지가 렌더링되거나 Next.js 웹사이트를 벗어났다가 돌아올 때 무효화.

 

 

 

요약

Next.js는 서버와 클라이언트에서 다양한 캐싱 메커니즘을 활용하여 데이터 요청과 페이지 렌더링을 최적화합니다. 이를 통해 불필요한 서버 왕복을 피하고, 페이지 로딩 속도를 높여 사용자 경험을 향상시킵니다. 각 캐시 메커니즘은 고유한 목적과 지속성 조건을 가지고 있으며, 이를 적절히 활용하는 것이 중요합니다. Next.js의 공식 문서를 참고하여 자세한 내용을 확인하고, 각 캐시 방법의 구현 세부 사항을 학습할 수 있습니다.

 

 

 

 

 

 

 

2.Next.js의 요청 캐싱 메커니즘 요약

 

Next.js는 성능을 최적화하고 중복된 데이터 요청을 방지하기 위해 여러 캐싱 메커니즘을 사용합니다.

특히 요청 기억(request memorization) 메커니즘을 활용하여 동일한 요청을 중복하지 않고 한 번만 처리하는 것이 중요합니다. 다음은 이 과정에 대한 자세한 설명입니다.

 

백엔드 서버와 메시지 페이지

  1. 백엔드 서버 실행: 별도의 프로세스로 백엔드 서버를 실행하여 데이터를 제공.
  2. 메시지 페이지 새로고침: Messages 페이지를 새로고침하면 백엔드 서버 로그에 요청 메시지가 표시됩니다.

 

문제 발생 시 해결 방법

  1. .next 폴더 삭제: Next.js 프로젝트에서 .next 폴더를 삭제하여 캐시 데이터를 초기화.
  2. 서버 재시작: 백엔드 서버와 Next.js 개발 서버를 다시 시작하여 문제 해결.

 

요청 기억(Request Memorization)

  1. 동일한 설정의 요청 방지: Next.js는 동일한 설정을 가진 데이터 요청을 저장하여 중복 요청을 방지.
  2. 요청 기억 작동 범위: 단일 요청 동안에만 발생.

 

예시 상황

  1. 중복 요청 발생: MessagesPage와 MessagesLayout에서 동일한 데이터를 요청하지만, 다른 헤더 구성을 가지고 있어 백엔드에서 두 번의 요청이 발생.
  2. 헤더 구성 제거: 두 곳의 요청에서 헤더 구성을 제거하여 정확히 동일한 요청 서명을 가짐.
  3. 결과: 헤더 구성 제거 후, Next.js는 두 개의 요청을 하나로 병합하여 중복 요청을 방지.

 

.next 폴더 삭제와 서버 재시작

  1. .next 폴더 삭제: Next.js 애플리케이션을 초기화하기 위해 .next 폴더 삭제.
  2. 서버 재시작: Next.js 개발 서버를 다시 시작하여 새로운 데이터로 초기화.

 

요청 기억의 구현

  1. 중복 요청 피하기: 동일한 구성을 가진 fetch 요청의 경우, Next.js는 하나의 요청만 보내고 응답을 재사용.
  2. 결과 확인: 백엔드 로그를 통해 두 개의 요청 대신 하나의 요청만 추가된 것을 확인.

 

요약

Next.js의 요청 기억 메커니즘은 동일한 설정을 가진 데이터 요청을 저장하여 중복 요청을 방지하는 데 사용됩니다. 이를 통해 불필요한 서버 왕복을 줄이고 애플리케이션 성능을 최적화할 수 있습니다. Next.js 프로젝트에서 .next 폴더를 삭제하고 서버를 재시작함으로써 캐시 데이터를 초기화하고, 동일한 요청 서명을 가지도록 헤더 구성을 조정하여 중복 요청을 피할 수 있습니다.

 

 

 

 

 

 

3.Next.js의 데이터 캐싱 메커니즘 요약

 

Next.js는 성능 최적화와 중복된 데이터 요청을 방지하기 위해 여러 캐싱 메커니즘을 제공합니다. 특히 요청 기억(request memorization)과 데이터 캐시 기능을 통해 효율적으로 데이터를 관리합니다. 다음은 이 과정에 대한 자세한 설명입니다.

데이터 캐시(Data Cache)

  • 기본 동작: Next.js는 fetch 함수를 통해 백엔드에서 데이터를 가져올 때, 해당 데이터를 서버 측 캐시에 저장하고 재사용합니다. 이는 데이터 소스로의 불필요한 추가 요청을 방지합니다.
  • 캐시된 데이터 재사용: 페이지를 다시 로드하거나 다른 페이지로 이동한 후 돌아와도, 새로운 요청 없이 캐시된 데이터를 사용합니다.
  •  

캐시 설정 옵션

  • force-cache: 기본적으로 Next.js는 이 옵션을 사용하여 가능한 한 데이터를 캐시하고 재사용합니다.
  • no-store: 이 옵션을 설정하면 Next.js는 데이터를 캐시하지 않고 항상 새로운 요청을 보내도록 강제합니다. 이를 통해 매 요청마다 새로운 데이터를 가져올 수 있습니다.

 

// no-store 옵션 설정 예시
fetch('api/endpoint', { cache: 'no-store' });

 

데이터 캐시 재검증

  • revalidate 설정: fetch 함수의 next 설정을 사용하여 캐시된 데이터를 일정 시간(초) 동안만 재사용하도록 지정할 수 있습니다. 예를 들어, revalidate: 5로 설정하면 Next.js는 캐시된 데이터를 5초 동안 재사용하고, 그 후에는 새로운 데이터를 가져옵니다.

 

// revalidate 설정 예시
fetch('api/endpoint', { next: { revalidate: 5 } });

 

예시 상황

  1. 초기 요청 이후: 페이지를 다시 로드하거나 다른 페이지로 갔다가 돌아와도 백엔드로 더 이상 요청이 전송되지 않음. 이는 데이터 캐시 덕분입니다.
  2. no-store 설정 사용: 이 설정을 통해 매 요청마다 새로운 데이터를 가져오게 설정할 수 있습니다.
  3. revalidate 설정 사용: 캐시된 데이터를 일정 시간 동안만 재사용하도록 설정할 수 있습니다. 설정된 시간이 지나면 새로운 요청을 보냅니다.

실습 예시

  1. 캐시 설정 변경 전: Messages 페이지와 MessagesLayout에서 동일한 데이터를 요청하지만, 다른 헤더 구성을 가지므로 두 번의 요청이 발생.
  2. 캐시 설정 변경 후: 헤더 구성을 동일하게 맞추면 Next.js는 요청 기억 메커니즘을 통해 두 개의 요청을 하나로 병합.
  3. 캐시 설정 옵션 적용: no-store와 revalidate 옵션을 통해 필요한 경우 데이터 캐시를 비활성화하거나 일정 시간 이후 데이터를 재검증하도록 설정.

 

 

 

unstable_cache

import Messages from '@/components/messages';
import { unstable_cache } from 'next/cache';
//export const revalidate =5;
//export const dynamic = "force-dynamic";


export default async function MessagesPage() {
  const response = await fetch('http://localhost:8080/messages');
  const messages = await response.json();


  if (!messages || messages.length === 0) {
    return <p>메시지를 발견할수 없습니다.</p>;
  }

  return <Messages messages={messages} />;
}

 

 

 

 

결론

Next.js의 요청 기억과 데이터 캐시 메커니즘을 통해 애플리케이션의 성능을 최적화할 수 있습니다. fetch 함수의 설정을 통해 데이터의 캐시 동작을 세밀하게 조정할 수 있으며, 이를 통해 불필요한 중복 요청을 방지하고, 필요한 경우에는 새로운 데이터를 가져올 수 있습니다. Next.js의 이러한 기능을 잘 활용하면 더 나은 사용자 경험을 제공할 수 있습니다.

 

 

 

 

 

 

 

 

 

4.Next.js에서 데이터 캐싱 제어 방법 요약

 

Next.js는 데이터를 캐싱하고 재사용하여 성능을 최적화합니다. 이를 제어하기 위한 다양한 방법이 있으며, 특정 요청뿐만 아니라 파일 전체에 대한 설정도 가능합니다. 다음은 데이터 캐싱을 제어하는 다양한 방법을 설명합니다.

 

1. Fetch 함수 설정

  • 캐시 설정: fetch 함수의 cache 옵션을 사용하여 캐싱 동작을 제어할 수 있습니다.
    • force-cache: 데이터를 가능한 한 캐시하고 재사용합니다.
    • no-store: 데이터를 캐시하지 않고 매 요청마다 새 데이터를 가져옵니다.

 

 

fetch('api/endpoint', { cache: 'no-store' });


 

revalidate 설정: fetch 함수의 next 옵션을 사용하여 캐시된 데이터를 일정 시간(초) 동안만 재사용하도록 설정할 수 있습니다.

 

fetch('api/endpoint', { next: { revalidate: 5 } });


 

2. 파일 전체 설정

파일 내 모든 fetch 요청에 대해 캐싱 동작을 일관되게 적용할 수 있는 상수를 사용할 수 있습니다.

  • revalidate 상수: 이 상수는 파일 내 모든 fetch 요청에 대해 캐시 재검증 시간을 설정합니다. Next.js는 이 상수를 인식하고 캐싱 동작을 제어합니다.

 

export const revalidate = 5;


 

dynamic 상수: 이 상수는 파일 전체에 대해 캐싱 동작을 설정합니다.

  • auto: 기본값으로, 자동으로 캐싱 동작을 결정합니다.
  • force-dynamic: 데이터를 캐시하지 않고 매 요청마다 새 데이터를 가져옵니다.
  • force-static: 데이터를 캐시하고 새 데이터를 가져오지 않습니다.

 

export const dynamic = 'force-dynamic';

 

 

특수 함수 사용

특정 컴포넌트에서 캐싱을 제어할 수 있는 특별한 함수를 사용할 수 있습니다.

  • unstable_noStore 함수: 특정 컴포넌트 내에서 호출하여 해당 컴포넌트의 모든 데이터 요청에 대해 캐싱을 비활성화합니다. 이 함수는 next/cache 패키지에서 가져올 수 있으며, 향후 unstable 접두사가 제거될 수 있습니다.

 

import { unstable_noStore } from 'next/cache';

unstable_noStore();


 

 

예시 상황

  1. 캐시 설정 변경 전: Messages 페이지와 MessagesLayout에서 각각 다른 헤더 구성을 가진 요청을 보냅니다. 결과적으로 백엔드로 두 번의 요청이 발생합니다.
  2. 캐시 설정 변경 후: 동일한 헤더 구성을 맞추면 Next.js는 요청 기억 메커니즘을 통해 두 개의 요청을 하나로 병합합니다.
  3. 파일 전체 설정 적용: revalidate 상수를 사용하여 파일 내 모든 fetch 요청에 대해 캐시 재검증 시간을 설정합니다.
  4. 특수 함수 사용: unstable_noStore 함수를 사용하여 특정 컴포넌트 내의 캐싱을 비활성화합니다.

 

결론

Next.js의 다양한 캐싱 제어 방법을 통해 애플리케이션 성능을 최적화하고, 필요한 경우 데이터를 새로 가져올 수 있습니다.

이를 통해 더 나은 사용자 경험을 제공할 수 있으며, 특정 요구사항에 맞게 캐싱 동작을 세밀하게 조정할 수 있습니다.

 

 

 

 

 

 

 

 

 

5.Next.js의 전체 라우트 캐시 제어 방법 요약

 

Next.js는 데이터 캐시 외에도 전체 라우트 캐시를 사용하여 빌드 시 미리 렌더링된 페이지를 캐싱합니다. 이러한 캐시 설정은 프로덕션 환경에서 페이지 로딩 속도를 최적화하지만, 실시간 데이터 업데이트를 반영하지 못할 수 있습니다. 이를 제어하기 위한 다양한 방법이 있습니다.

1. 전체 라우트 캐시

Next.js는 빌드 시 애플리케이션의 모든 페이지를 미리 렌더링하여 캐시합니다. 이는 프로덕션 서버가 실행 중일 때 성능을 최적화합니다. 단, 동적 매개변수가 있는 페이지는 기본적으로 캐시되지 않습니다.

 

npm run build
npm start

 

빌드 후, 프로덕션 서버는 미리 렌더링된 페이지를 제공하며, 백엔드에 새로운 로그가 생성되지 않습니다.

 

 

2. 전체 라우트 캐시 비활성화

특정 페이지에 대한 전체 라우트 캐시를 비활성화하려면 dynamic 상수를 force-dynamic으로 설정합니다. 이 설정을 사용하면 Next.js는 해당 페이지를 항상 다시 렌더링하여 최신 데이터를 가져옵니다.

 

export const dynamic = 'force-dynamic';

 

이 설정을 저장한 후 프로젝트를 다시 빌드하고 프로덕션 서버를 시작하면, 해당 페이지에 대한 모든 요청이 항상 새롭게 렌더링됩니다.

 

npm run build
npm start

 

이제 페이지를 새로고침할 때마다 백엔드 로그에 새로운 로그 메시지가 나타나게 됩니다.

 

 

3. 캐시 재검증

데이터가 변경될 때 특정 페이지의 캐시를 재검증하려면 revalidatePath 함수를 사용할 수 있습니다.

이는 데이터 변경 시 캐시를 무효화하고 새 데이터를 가져오도록 합니다.

import { revalidatePath } from 'next/cache';

revalidatePath('/path-to-revalidate');

이 접근 방법은 데이터를 업데이트할 때마다 해당 페이지의 캐시를 무효화하므로 항상 최신 데이터를 제공할 수 있습니다.

 

 

4. 데이터베이스와의 캐시 관리

Next.js 애플리케이션에서 관리하는 데이터베이스와 같은 다른 데이터 소스에 요청을 보낼 때도 캐시를 관리할 수 있습니다. 다음 강의에서 이를 다룰 예정입니다.

 

 

결론

Next.js는 데이터 캐시와 전체 라우트 캐시를 통해 성능을 최적화하지만, 실시간 데이터 업데이트를 반영하기 위해 캐시 설정을 제어해야 합니다.

dynamic 상수, revalidatePath 함수 등의 다양한 방법을 사용하여 필요한 경우 캐시를 비활성화하거나 재검증할 수 있습니다.

이러한 설정을 통해 최신 데이터를 제공하면서도 성능을 최적화할 수 있습니다.

 

 

 

 

 

 

 

6. revalidatePath 및 revalidateTag를 사용한 온디맨드 캐시 무효화

 

Next.js에서 캐시를 제어하고 재검증하는 다양한 방법을 배웠습니다. 캐시 설정과 재검증 방법을 비교하고 각각의 장점과 사용 사례를 정리해보겠습니다.

1. 캐시 설정

캐시를 설정하는 다양한 방법이 있습니다.

a. dynamic 상수 설정

  • force-dynamic: 모든 요청에 대해 항상 데이터를 다시 가져옵니다.
  • force-static: 캐시를 강제하며 새로운 데이터를 가져오지 않습니다.

 

export const dynamic = 'force-dynamic';

 

b. fetch 함수 설정

  • no-store 옵션: 데이터 캐시를 완전히 비활성화합니다.
  • revalidate 옵션: 특정 시간 간격으로 캐시를 재검증합니다.

 

fetch('/api/data', { cache: 'no-store' });
fetch('/api/data', { next: { revalidate: 5 } });

 

2. 캐시 재검증

캐시 재검증은 데이터가 변경될 때 특정 캐시 부분을 무효화하고 새 데이터를 가져오도록 하는 방법입니다.

a. revalidatePath 함수

  • 특정 경로의 캐시를 재검증합니다.
  • 장점: 필요할 때만 캐시를 무효화하여 효율적으로 최신 데이터를 가져옵니다.
  •  
import { revalidatePath } from 'next/cache';

revalidatePath('/messages');

 

revalidateTag 함수

  • 특정 태그에 할당된 모든 캐시된 데이터를 재검증합니다.
  • 장점: 여러 페이지나 컴포넌트에서 동일한 태그를 사용하여 한 번의 호출로 여러 캐시를 재검증할 수 있습니다.

 

import { revalidateTag } from 'next/cache';

revalidateTag('msg');

 

. 사용 예시

a. revalidatePath 예시

  • 특정 경로의 캐시를 명시적으로 재검증합니다.

 

import { revalidatePath } from 'next/cache';

function updateData() {
  // 데이터 변경 후
  revalidatePath('/messages');
}

 

revalidateTag 예시

  • fetch 요청 시 태그를 할당하고, 해당 태그를 기반으로 캐시를 재검증합니다.
  • fetch 요청 시 태그 설정:

 

fetch('/api/data', { next: { tags: ['msg'] } });

 

태그 기반 캐시 재검증

 

import { revalidateTag } from 'next/cache';

function handleSubmit() {
  // 데이터 변경 후
  revalidateTag('msg');
}

 

결론

  • 캐시 비활성화: force-dynamic, no-store 등 설정으로 캐시를 비활성화.
  • 캐시 재검증: revalidatePath, revalidateTag 함수로 필요할 때만 캐시를 무효화.

각 방법의 장단점을 이해하고, 상황에 맞게 적절한 방법을 선택하여 캐시를 관리하면 효율적이고 최신 데이터를 제공할 수 있습니다.

 

 

 

 

 

 

 

 

 

 

 

 

7.커스텀 데이터 소스에 대한 요청 메모화 설정

데이터베이스와 같은 자체 데이터 소스 사용 시 캐시 관리 및 중복 요청 제거 방법

 

1. 배경 및 문제

외부 API 대신 SQLite 데이터베이스를 사용하여 데이터를 가져올 때도 캐시를 효과적으로 관리하고, 중복 요청을 제거해야 합니다. 외부 API 호출 시에는 fetch 함수를 통해 캐싱과 중복 요청 제거를 쉽게 할 수 있지만, 자체 데이터 소스를 사용할 때는 다른 방법이 필요합니다.

 

2. fetch 함수 사용 제거

외부 API 호출을 주석 처리하고 데이터베이스 함수를 직접 호출합니다. 이를 통해 SQLite 데이터베이스와 상호작용하는 getMessages와 addMessage 함수를 사용합니다.

 

3. SQLite 데이터베이스 함수

SQLite 데이터베이스를 관리하기 위해 better-sqlite3 패키지를 사용하여 동기적 데이터베이스 접근을 구현합니다.

 

// lib/db.js
const Database = require('better-sqlite3');
const db = new Database('messages.db');

// 메시지 가져오기 함수
function getMessages() {
    const stmt = db.prepare('SELECT * FROM messages');
    return stmt.all();
}

// 메시지 추가 함수
function addMessage(message) {
    const stmt = db.prepare('INSERT INTO messages (text) VALUES (?)');
    stmt.run(message);
}

module.exports = { getMessages, addMessage };

 

 

4. 데이터 소스를 직접 사용하는 컴포넌트

MessagesPage와 NewMessagePage 컴포넌트에서 데이터베이스 함수를 직접 호출합니다.

// pages/messages.js
import { getMessages } from '../lib/db';

export default function MessagesPage() {
    const messages = getMessages();

    return (
        <div>
            {messages.map(msg => (
                <p key={msg.id}>{msg.text}</p>
            ))}
        </div>
    );
}

// pages/new-message.js
import { addMessage } from '../lib/db';

export default function NewMessagePage() {
    const handleSubmit = (e) => {
        e.preventDefault();
        const message = e.target.elements.message.value;
        addMessage(message);
    };

    return (
        <form onSubmit={handleSubmit}>
            <input name="message" />
            <button type="submit">Add Message</button>
        </form>
    );
}

 

 

5. 중복 요청 문제

페이지 로드 시 데이터베이스 접근이 중복되는 문제를 해결하기 위해 React의 cache 함수를 사용합니다.

 

// pages/messages.js
import { getMessages as fetchMessages } from '../lib/db';
import { cache } from 'react';

// 중복 요청 제거를 위해 cache 함수로 감싸기
const getMessages = cache(fetchMessages);

export default function MessagesPage() {
    const messages = getMessages();

    return (
        <div>
            {messages.map(msg => (
                <p key={msg.id}>{msg.text}</p>
            ))}
        </div>
    );
}

 

 

6. React cache 함수

cache 함수는 한 요청 주기 내에서 동일한 함수 호출을 감싸고, 동일한 응답을 재사용하도록 합니다. 이로 인해 중복 요청을 제거하고, 동일한 데이터 소스에 대한 중복 접근을 방지할 수 있습니다.

 

7. 전체 라우트 캐시 및 데이터 캐시 문제

빌드 시 전체 라우트 캐시로 인해 데이터가 갱신되지 않는 문제를 해결하려면 dynamic 상수를 force-dynamic으로 설정합니다.

 

// pages/messages.js
export const dynamic = 'force-dynamic';

 

 

8. 최종 코드 예시

// lib/db.js
const Database = require('better-sqlite3');
const db = new Database('messages.db');

function getMessages() {
    const stmt = db.prepare('SELECT * FROM messages');
    return stmt.all();
}

function addMessage(message) {
    const stmt = db.prepare('INSERT INTO messages (text) VALUES (?)');
    stmt.run(message);
}

module.exports = { getMessages, addMessage };

// pages/messages.js
import { getMessages as fetchMessages } from '../lib/db';
import { cache } from 'react';

const getMessages = cache(fetchMessages);

export const dynamic = 'force-dynamic';

export default function MessagesPage() {
    const messages = getMessages();

    return (
        <div>
            {messages.map(msg => (
                <p key={msg.id}>{msg.text}</p>
            ))}
        </div>
    );
}

// pages/new-message.js
import { addMessage } from '../lib/db';

export default function NewMessagePage() {
    const handleSubmit = (e) => {
        e.preventDefault();
        const message = e.target.elements.message.value;
        addMessage(message);
    };

    return (
        <form onSubmit={handleSubmit}>
            <input name="message" />
            <button type="submit">Add Message</button>
        </form>
    );
}

 

 

이렇게 하면 데이터베이스와 상호작용할 때 중복 요청을 제거하고, 최신 데이터를 제공할 수 있습니다.

cache 함수를 통해 React에서 제공하는 캐시 기능을 활용하여 성능을 최적화할 수 있습니다.

 

 

 

 

 

 

 

 

 

 

8.자체 데이터 소스에 대해 NextJS 데이터 캐싱을 활용하는 방법

 

NextJS에서 외부 API 대신 데이터베이스와 같은 자체 데이터 소스를 사용할 때 데이터 캐싱과 중복 요청 제거를 활용하는 방법을 자세히 살펴보겠습니다. 이를 위해 unstable_cache 함수(이후에는 cache로 변경될 가능성 있음)를 사용합니다.

 

1. NextJS의 unstable_cache 함수 소개

unstable_cache 함수는 NextJS의 데이터 캐싱을 활성화하는 함수로, 특정 함수가 반환하는 데이터를 캐시합니다. 이를 통해 외부 API뿐만 아니라 자체 데이터 소스에서도 캐시 기능을 사용할 수 있습니다.

 

2. 기존 데이터베이스 함수 개선

기존의 데이터베이스 접근 함수들을 unstable_cache로 감싸서 캐싱 기능을 추가합니다.

SQLite 데이터베이스 함수

먼저 SQLite 데이터베이스를 관리하는 기존 함수를 수정합니다.

// lib/db.js
const Database = require('better-sqlite3');
const db = new Database('messages.db');

// 메시지 가져오기 함수
function getMessages() {
    const stmt = db.prepare('SELECT * FROM messages');
    return stmt.all();
}

// 메시지 추가 함수
function addMessage(message) {
    const stmt = db.prepare('INSERT INTO messages (text) VALUES (?)');
    stmt.run(message);
}

module.exports = { getMessages, addMessage };

 

 

3. NextJS의 unstable_cache 함수 사용

NextJS에서 제공하는 unstable_cache 함수를 사용하여 getMessages 함수를 감쌉니다. 이 함수는 기본적으로 프로미스를 반환하므로, async/await 키워드를 사용해야 합니다.

NextJS 데이터 캐시 함수 사용

NextJS의 unstable_cache 함수를 사용하여 캐싱 기능을 추가합니다.

// lib/db.js
const Database = require('better-sqlite3');
const db = new Database('messages.db');
const { unstable_cache } = require('next/cache');

// 메시지 가져오기 함수
const getMessages = () => {
    const stmt = db.prepare('SELECT * FROM messages');
    return stmt.all();
};

// 캐시된 getMessages 함수
const cachedGetMessages = unstable_cache(getMessages, ['messages']);

// 메시지 추가 함수
function addMessage(message) {
    const stmt = db.prepare('INSERT INTO messages (text) VALUES (?)');
    stmt.run(message);
}

module.exports = { getMessages: cachedGetMessages, addMessage };

 

4. 페이지 컴포넌트 수정

데이터를 가져오는 함수가 프로미스를 반환하므로, 컴포넌트에서 async/await를 사용하여 데이터를 가져옵니다.

 

 

// pages/messages.js
import { getMessages } from '../lib/db';

export const dynamic = 'force-dynamic';

export default async function MessagesPage() {
    const messages = await getMessages();

    return (
        <div>
            {messages.map(msg => (
                <p key={msg.id}>{msg.text}</p>
            ))}
        </div>
    );
}

// pages/new-message.js
import { addMessage } from '../lib/db';

export default function NewMessagePage() {
    const handleSubmit = async (e) => {
        e.preventDefault();
        const message = e.target.elements.message.value;
        await addMessage(message);
    };

    return (
        <form onSubmit={handleSubmit}>
            <input name="message" />
            <button type="submit">Add Message</button>
        </form>
    );
}

 

 

5. 결과 확인

개발 서버를 재시작하고 페이지를 로드하면 데이터가 캐시됩니다. 이후 페이지를 새로고침해도 데이터베이스에 대한 요청이 발생하지 않습니다.

 

npm run dev


 

 

요약

  1. NextJS의 unstable_cache 함수를 사용하여 자체 데이터 소스 함수의 반환값을 캐시할 수 있습니다.
  2. unstable_cache로 감싼 함수는 프로미스를 반환하므로, async/await 키워드를 사용해야 합니다.
  3. NextJS의 데이터 캐시를 통해 외부 API뿐만 아니라 자체 데이터 소스에서도 효율적으로 데이터를 캐시할 수 있습니다.

 

이 방법을 통해 NextJS 애플리케이션에서 데이터베이스와 같은 자체 데이터 소스를 사용하면서도 데이터 캐싱과 중복 요청 제거를 효과적으로 구현할 수 있습니다.

 

 

 

 

 

 

 

 

9.Next.js에서 캐시된 데이터를 무효화하여 최신 데이터를 표시하는 방법

 

 

1. revalidate 함수 사용

revalidate 함수 개요

  • revalidate 함수는 특정 경로(revalidatePath)나 특정 페이지에서 사용된 모든 캐시된 데이터를 무효화하고 새로운 데이터를 가져오도록 Next.js에 요청하는 함수입니다.
  • 데이터를 새로고침할 필요가 있는 경우, 예를 들어 새로운 메시지가 추가된 직후에 호출하여 캐시를 갱신할 수 있습니다.

 

사용 방법

import { revalidate } from 'next/cache';

async function addMessageAndRefresh(message) {
    // 메시지 추가 로직
    await addMessage(message);

    // 메시지 추가 후 데이터 캐시 무효화
    await revalidate('/messages');
}

 

  • revalidate 함수는 지정된 경로(/messages)에 대한 캐시를 무효화하고, 해당 경로를 다시 렌더링합니다.
  • 이는 페이지의 모든 캐시된 데이터를 재검증하고 새 데이터를 가져오도록 합니다.

 

2. revalidateTag 함수 사용

revalidateTag 함수 개요

  • revalidateTag 함수는 특정 데이터 태그를 가진 모든 캐시된 데이터를 무효화하고, 해당 데이터가 사용된 모든 페이지와 컴포넌트를 다시 렌더링하도록 Next.js에 요청하는 함수입니다.
  • 특히 다중 데이터 소스를 사용하는 경우 유용하며, 특정 태그에 대한 데이터를 모두 갱신할 수 있습니다.

 

import { revalidateTag } from 'next/cache';

async function addMessageAndRefreshWithTags(message) {
    // 메시지 추가 로직
    await addMessage(message);

    // 메시지 추가 후 특정 태그로 캐시된 데이터 무효화
    await revalidateTag('messages');
}

 

  • revalidateTag 함수는 지정된 태그(messages)를 가진 모든 캐시된 데이터를 무효화하고, 이 태그를 사용하는 모든 페이지와 컴포넌트를 재실행합니다.
  • 이 방법을 사용하면 다양한 데이터 소스를 효과적으로 관리하면서 필요한 데이터만 갱신할 수 있습니다.

 

요약

 

  • revalidate와 revalidateTag 함수는 Next.js에서 데이터 캐싱을 관리하고 새로운 데이터가 추가되었을 때 캐시를 갱신하는 데 중요한 역할을 합니다.
  • revalidate 함수는 특정 경로의 모든 캐시를 무효화하고 데이터를 다시 가져오도록 요청합니다.
  • revalidateTag 함수는 특정 데이터 태그를 가진 모든 캐시된 데이터를 무효화하고, 해당 태그를 사용하는 모든 페이지와 컴포넌트를 재실행합니다.
  • 이를 통해 새로운 데이터가 추가될 때 캐시된 데이터를 효과적으로 갱신하고, 사용자에게 최신 정보를 제공할 수 있습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

about author

PHRASE

Level 60  라이트

돼지가 어금니로 사람을 해치는 위험이 없도록 하려면 이빨을 빼거나 거세(去勢)하면 노력은 적게 들고 그 공은 크다. 세상을 다스리려면 형벌로써 하는 것보다는 먼저 백성의 양심을 기르는 것이 좋다. -역경

댓글 ( 0)

댓글 남기기

작성