-
[Next.js] URL query string 관리하기Next.js 2023. 4. 10. 23:57
Next.js 13의 useSearchParams hook은 현재 URL의 query string을 읽을 수 있게 해주는 hook으로, read-only 버전의 URLSearchParams 인터페이스를 return합니다. useSearchParams hook의 사용 방법은 아래와 같습니다.
// url: /?note=4%7C10 import { useSearchParams } from 'next/navigation'; const searchParams = useSearchParams(); console.log(searchParams.get('note')); // 4|10 console.log(searchParams.has('note')); // true console.log(searchParams.has('brand')); // false
그러나 Next.js의 useSearchParams hook은 read-only입니다. 때문에 공식 문서에서는 query string을 추가하고, 업데이트하고, 삭제하기 위해서는 URLSearchParams 인터페이스를 활용하는 방식을 예시로 제시하고 있었습니다.
// Next.js 공식문서의 Updating searchParams 예시 export default function ExampleClientComponent() { const router = useRouter() const pathname = usePathname() const searchParams = useSearchParams()! // Get a new searchParams string by merging the current // searchParams with a provided key/value pair const createQueryString = useCallback( (name: string, value: string) => { const params = new URLSearchParams(searchParams) params.set(name, value) return params.toString() }, [searchParams] ) return ( <> <p>Sort By</p> {/* using useRouter */} <button onClick={() => { // <pathname>?sort=asc router.push(pathname + '?' + createQueryString('sort', 'asc')) }} > ASC </button> {/* using <Link> */} <Link href={ // <pathname>?sort=desc pathname + '?' + createQueryString('sort', 'desc') } > DESC </Link> </> ) }
이러한 예시와 검색 결과를 바탕으로 아래와 같은 cutom hook을 만들었습니다.
import { usePathname, useRouter, useSearchParams } from 'next/navigation'; function useCustomSearchParams<T extends Partial<{ [key: string]: string[] | undefined }>>() { const searchParams = useSearchParams(); const pathname = usePathname(); const router = useRouter(); const urlSearchParams = searchParams ? new URLSearchParams(searchParams) : null; function setSearchParams(params: Partial<T>) { Object.entries(params).forEach(([key, value]) => { if (!value.length) urlSearchParams?.delete(key); else urlSearchParams?.set(key, String(value.join('|'))); }); const paramsToString = urlSearchParams?.toString(); const query = paramsToString ? `?${paramsToString}` : ''; router.push(`${pathname}${query}`); } return { searchParams, setSearchParams }; } export default useCustomSearchParams;
위의 hook은 query string을 활용하여 필터 기능을 구현하기 위해 만들었는데, 관리해야 하는 필터의 항목이 두 개 였기 때문에 setSearchParams 함수에 객체 형태의 parameter를 전달할 수 있도록 구현했습니다.
이 때 setSearchParams 함수는 parameter로 전달 받은 객체를 순회하며 key에 해당하는 value의 length가 1 이상일 경우 urlSearchParams에 key, value를 set 하고, value의 length가 0일 경우 urlSearchParams에서 key를 삭제합니다.
이후 urlSearchParams를 string 형태로 변환하고, 이를 pathname과 함께 router에 push해 주면 "/?brand=1%7C2¬e=4" 의 형태로 URL을 관리할 수 있습니다.
참고 자료
- https://nextjs.org/docs/app/api-reference/functions/use-search-params
- https://developer.mozilla.org/ko/docs/Web/API/URLSearchParams
'Next.js' 카테고리의 다른 글
[Next.js] Route Handlers를 활용하여 storage에 이미지 업로드하기 (0) 2023.07.03 [Next.js] next/image src 외부 이미지 URL로 설정하기 (0) 2023.06.22