useSearchParams
useSearchParams
는 현재 URL의 쿼리 문자열을 읽을 수 있게 해주는 클라이언트 컴포넌트 훅입니다.
useSearchParams
는 URLSearchParams
인터페이스의 읽기 전용 버전을 반환합니다.
"use client";
import { useSearchParams } from "next/navigation";
export default function SearchBar() {
const searchParams = useSearchParams();
const search = searchParams.get("search");
// URL -> `/dashboard?search=my-project`
// `search` -> 'my-project'
return <>Search: {search}</>;
}
"use client";
import { useSearchParams } from "next/navigation";
export default function SearchBar() {
const searchParams = useSearchParams();
const search = searchParams.get("search");
// URL -> `/dashboard?search=my-project`
// `search` -> 'my-project'
return <>Search: {search}</>;
}
매개변수
const searchParams = useSearchParams();
useSearchParams
는 매개변수를 받지 않습니다.
반환값
useSearchParams
는 URLSearchParams
인터페이스의 읽기 전용 버전을 반환하며, 여기에는 URL의 쿼리 문자열을 읽기 위한 유틸리티 메서드가 포함되어 있습니다:
-
URLSearchParams.get()
: 검색 매개변수와 관련된 첫 번째 값을 반환합니다. 예를 들어:URL searchParams.get("a")
/dashboard?a=1
'1'
/dashboard?a=
''
/dashboard?b=3
null
/dashboard?a=1&a=2
'1'
- 모든 값을 가져오려면getAll()
사용 -
URLSearchParams.has()
: 주어진 매개변수가 존재하는지 여부를 나타내는 불리언 값을 반환합니다. 예를 들어:URL searchParams.has("a")
/dashboard?a=1
true
/dashboard?b=3
false
-
URLSearchParams
의 다른 읽기 전용 메서드에 대해 자세히 알아보세요. 여기에는getAll()
,keys()
,values()
,entries()
,forEach()
,toString()
이 포함됩니다.
알아두면 좋은 점:
useSearchParams
는 클라이언트 컴포넌트 훅이며 서버 컴포넌트에서는 지원되지 않습니다. 이는 부분 렌더링 중 오래된 값을 방지하기 위함입니다.- 애플리케이션에
/pages
디렉토리가 포함되어 있다면,useSearchParams
는ReadonlyURLSearchParams | null
을 반환합니다.null
값은 마이그레이션 중 호환성을 위한 것으로,getServerSideProps
를 사용하지 않는 페이지의 사전 렌더링 중에는 검색 매개변수를 알 수 없기 때문입니다.
정적 렌더링
경로가 정적으로 렌더링되는 경우, useSearchParams
를 호출하면 가장 가까운 Suspense
경계까지의 클라이언트 컴포넌트 트리가 클라이언트 측에서 렌더링됩니다.
이를 통해 경로의 일부를 정적으로 렌더링하면서 useSearchParams
를 사용하는 동적 부분은 클라이언트 측에서 렌더링할 수 있습니다.
useSearchParams
를 사용하는 클라이언트 컴포넌트를 <Suspense/>
경계로 감싸는 것을 권장합니다. 이렇게 하면 그 위의 클라이언트 컴포넌트들을 정적으로 렌더링하여 초기 HTML의 일부로 보낼 수 있습니다. 예시를 참조하세요.
예를 들어:
"use client";
import { useSearchParams } from "next/navigation";
export default function SearchBar() {
const searchParams = useSearchParams();
const search = searchParams.get("search");
// 정적 렌더링을 사용할 때 이 로그는 서버에서 기록되지 않습니다
console.log(search);
return <>Search: {search}</>;
}
"use client";
import { useSearchParams } from "next/navigation";
export default function SearchBar() {
const searchParams = useSearchParams();
const search = searchParams.get("search");
// 정적 렌더링을 사용할 때 이 로그는 서버에서 기록되지 않습니다
console.log(search);
return <>Search: {search}</>;
}
import { Suspense } from "react";
import SearchBar from "./search-bar";
// Suspense 경계에 대한 폴백으로 전달되는 이 컴포넌트는
// 초기 HTML에서 검색 바 대신 렌더링됩니다.
// React 하이드레이션 중에 값을 사용할 수 있게 되면
// 폴백은 `<SearchBar>` 컴포넌트로 대체됩니다.
function SearchBarFallback() {
return <>placeholder</>;
}
export default function Page() {
return (
<>
<nav>
<Suspense fallback={<SearchBarFallback />}>
<SearchBar />
</Suspense>
</nav>
<h1>Dashboard</h1>
</>
);
}
import { Suspense } from "react";
import SearchBar from "./search-bar";
// Suspense 경계에 대한 폴백으로 전달되는 이 컴포넌트는
// 초기 HTML에서 검색 바 대신 렌더링됩니다.
// React 하이드레이션 중에 값을 사용할 수 있게 되면
// 폴백은 `<SearchBar>` 컴포넌트로 대체됩니다.
function SearchBarFallback() {
return <>placeholder</>;
}
export default function Page() {
return (
<>
<nav>
<Suspense fallback={<SearchBarFallback />}>
<SearchBar />
</Suspense>
</nav>
<h1>Dashboard</h1>
</>
);
}
동작
동적 렌더링
경로가 동적으로 렌더링되는 경우, useSearchParams
는 클라이언트 컴포넌트의 초기 서버 렌더링 중에 서버에서 사용할 수 있습니다.
예를 들어:
"use client";
import { useSearchParams } from "next/navigation";
export default function SearchBar() {
const searchParams = useSearchParams();
const search = searchParams.get("search");
// 이는 초기 렌더링 중에 서버에서 기록되고
// 이후 탐색에서는 클라이언트에서 기록됩니다.
console.log(search);
return <>Search: {search}</>;
}
"use client";
import { useSearchParams } from "next/navigation";
export default function SearchBar() {
const searchParams = useSearchParams();
const search = searchParams.get("search");
// 이는 초기 렌더링 중에 서버에서 기록되고
// 이후 탐색에서는 클라이언트에서 기록됩니다.
console.log(search);
return <>Search: {search}</>;
}
import SearchBar from "./search-bar";
export const dynamic = "force-dynamic";
export default function Page() {
return (
<>
<nav>
<SearchBar />
</nav>
<h1>Dashboard</h1>
</>
);
}
import SearchBar from "./search-bar";
export const dynamic = "force-dynamic";
export default function Page() {
return (
<>
<nav>
<SearchBar />
</nav>
<h1>Dashboard</h1>
</>
);
}
알아두면 좋은 점:
dynamic
라우트 세그먼트 구성 옵션을force-dynamic
으로 설정하면 동적 렌더링을 강제할 수 있습니다.
서버 컴포넌트
페이지
페이지 (서버 컴포넌트)에서 검색 매개변수에 접근하려면 searchParams
prop을 사용하세요.
레이아웃
페이지와 달리 레이아웃 (서버 컴포넌트)은 searchParams
prop을 받지 않습니다. 이는 공유 레이아웃이 탐색 중에 다시 렌더링되지 않기 때문에 탐색 사이에 오래된 searchParams
가 생길 수 있기 때문입니다. 자세한 설명을 참조하세요.
대신, 페이지 searchParams
prop을 사용하거나 클라이언트 컴포넌트에서 useSearchParams
훅을 사용하세요. 이는 최신 searchParams
로 클라이언트에서 다시 렌더링됩니다.
예시
searchParams
업데이트하기
useRouter
또는 Link
를 사용하여 새로운 searchParams
를 설정할 수 있습니다. 탐색이 수행된 후, 현재 page.js
는 업데이트된 searchParams
prop을 받게 됩니다.
"use client";
export default function ExampleClientComponent() {
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
// 현재 searchParams를 제공된 키/값 쌍과 병합하여
// 새로운 searchParams 문자열을 얻습니다
const createQueryString = useCallback(
(name: string, value: string) => {
const params = new URLSearchParams(searchParams.toString());
params.set(name, value);
return params.toString();
},
[searchParams]
);
return (
<>
<p>정렬 기준</p>
{/* useRouter 사용 */}
<button
onClick={() => {
// <pathname>?sort=asc
router.push(pathname + "?" + createQueryString("sort", "asc"));
}}
>
ASC
</button>
{/* <Link> 사용 */}
<Link
href={
// <pathname>?sort=desc
pathname + "?" + createQueryString("sort", "desc")
}
>
DESC
</Link>
</>
);
}
"use client";
export default function ExampleClientComponent() {
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
// 현재 searchParams를 제공된 키/값 쌍과 병합하여
// 새로운 searchParams 문자열을 얻습니다
const createQueryString = useCallback(
(name, value) => {
const params = new URLSearchParams(searchParams);
params.set(name, value);
return params.toString();
},
[searchParams]
);
return (
<>
<p>정렬 기준</p>
{/* useRouter 사용 */}
<button
onClick={() => {
// <pathname>?sort=asc
router.push(pathname + "?" + createQueryString("sort", "asc"));
}}
>
ASC
</button>
{/* <Link> 사용 */}
<Link
href={
// <pathname>?sort=desc
pathname + "?" + createQueryString("sort", "desc")
}
>
DESC
</Link>
</>
);
}
버전 기록
버전 | 변경 사항 |
---|---|
v13.0.0 | useSearchParams 도입됨. |