[Next.js] App Router - Next.js 15의 비동기 searchParams 이해

Melcoding·2026년 1월 12일

Next.js

목록 보기
15/27

개념 설명

Next.js 15 버전부터 도입된 서버 컴포넌트의 핵심적 변화. 기존에 동기적으로 접근 가능했던 searchParams, params, cookies, headers 등이 모두 Promise 기반의 비동기 API로 전환.
이는 Next.js의 새로운 렌더링 패러다임인 부분 프리렌더링(Partial Prerendering, PPR)스트리밍 성능을 극대화하기 위한 구조적 설계.

사용 상황 예시

  • 동적 검색 결과 페이지: 사용자가 입력한 검색어(q)에 따라 실시간으로 서버에서 데이터를 필터링하여 보여줄 때 사용.
  • 페이지네이션 구현: URL의 page 쿼리 파라미터를 읽어 해당 페이지의 데이터만 fetch할 때 필수.
  • 필터링 및 정렬: 가격순, 최신순 등 사용자의 선택 옵션을 서버 컴포넌트에서 반영할 때 활용.

기본 문법

서버 컴포넌트에서 searchParams를 다루는 가장 표준적인 방법. async 함수 선언과 await 키워드 활용이 핵심.

// Next.js 15 서버 컴포넌트 예시
import { Suspense } from "react";

// 1. 타입을 Promise로 정의
type Props = {
  searchParams: Promise<{ [key: string]: string | string[] | undefined }>;
};

export default async function Page({ searchParams }: Props) {
  // 2. await를 통한 Promise 해제 및 값 추출
  const { q } = await searchParams;

  return (
    <div>
      <h1>검색 결과: {q}</h1>
      {/* 3. 추출한 값을 하위 컴포넌트로 전달 */}
      <Suspense fallback={<p>로딩 중...</p>}>
        <SearchResult query={q as string} />
      </Suspense>
    </div>
  );
}

자주 하는 실수

  • 동기적 접근 시도: await 없이 searchParams.q와 같이 직접 접근 시 런타임 에러 또는 정의되지 않은 값 반환 가능성 존재.
  • async 키워드 누락: 컴포넌트 함수 자체를 async로 선언하지 않아 내부에서 await를 사용하지 못하는 상황 빈번.
  • 타입 정의 오류: TypeScript 환경에서 기존의 일반 객체 타입 대신 Promise 제네릭 타입을 명시하지 않아 발생하는 타입 체킹 오류 주의.

핵심 요약

  • Next.js 15부터 searchParams가 Promise 객체로 변경됨에 따른 비동기 처리 필수.
  • 서버 컴포넌트 내에서 async/await 패턴을 사용하여 안전하게 쿼리 데이터 추출.
  • PPR 및 스트리밍 성능 최적화를 위한 프레임워크 차원의 의도적인 아키텍처 변화.

출처: 한 입 크기로 잘라먹는 Next.js(v15)

0개의 댓글