[Next.js] usePathname / useSearchParams

Hwang Won Tae·2023년 6월 15일
6

Front-end

목록 보기
7/9
post-thumbnail

Next.js를 통해 프로젝트를 진행하던 중에 NextRouter was not mounted. 에러가 발생했다.
ServerComponent에 useRouter를 import하면서 발생한 에러이다.
공식 문서를 찾아보니 usePathnameuseSearchParams에 대한 내용이 있으니
본문에서 자세히 알아보자.

혹시나 ServerComponent가 뭐지? 싶다면 Next.js의 13 베타 버전에 대한 내용이니
여기서 잠깐 훑어보면 대충 짐작은 갈 것이다.

=> [Next.js] Server/Client Component

Failed to Compile

Uncaught Error: NextRouter was not mounted. https://nextjs.org/docs/messages/next-router-not-mounted
at useRouter (webpack-internal:///(app-client)/./node_modules/next/dist/client/router.js:141:15)

/[id]/page.tsx 내에서 params 값을 가져오기 위해 useRouter를 import 하자마자 발생한 에러이다.

Server Component에서 최상단에 "use client";만 달아준다면 모든 Hook을 사용할 수 있던게 아니었던 것인가!

공식 문서 내용은 다음과 같다

The new useRouter hook should be imported from next/navigation and not next/router
The pathname string has been removed and is replaced by usePathname()
The query object has been removed and is replaced by useSearchParams()
router.events is not currently supported. See below.

요약하자면

이제 문자열 useRouter().pathname과 객체 useRouter().query는 마이그레이션 됐다 ㅅㄱ

그렇다. 이제 더 이상 params 값을 호출하기 위해 useRouter 훅을 가져오는 것이 아니라
usePathnameuseSearchParams 훅을 가져다가 사용하면 된다.

usePathname

현재 url을 확인할 수 있는 훅이다. 쿼리스트링 값은 제외하고 가져온다.

'use client'
 
import { usePathname } from 'next/navigation'
 
export default function SearchBar() {
  const pathname = usePathname();
 
  // URL -> `/dashboard?search=my-project`
  // `Search: /dashboard`
  return <>Search: {pathname}</>
}
URLreturned value
/'/'
/dashboard'/dashboard'
/dashboard?v=2/dashboard'
/blog/hello-world/blog/hello-world'

useSearchParams

쿼리 스트링을 하기 위한 훅으로 아래 예시와 함께 살펴보자.

'use client'
 
import { useSearchParams } from 'next/navigation'
 
export default function SearchBar() {
  const searchParams = useSearchParams()
 
  const getItem = searchParams.get('search')
  const hasItem = searchParams.has('search')
 
  // URL -> `/dashboard?search=my-project`
  // get -> `Search: my-project`
  // has -> `true`
  return <>Search: {search}</>0
}

get 메서드로 query의 value 값을 가져올 수 있고
has 메서드로 query 키의 존재 여부를 확인할 수 있다.

params 값만 가져올 수는 없을까?

그렇다면 usePathname 훅으로 기존의 params 값을 가져와야 하는가?

만약 /movie/genre/5라고 가정한다면 split("/")로 잘라서 사용하는 것은 굉장히 비효율적이다.

Stack Overflow의 한 질답에서 답을 찾을 수 있었다.

export default function Page({ params }: { params: { id: number } }) {
  
  // URL -> `/movie/genre/5`
  // `ID: 5`
  return <>ID: {params.id}</>;
}

// app/movie/genre/[id]/page.tsx

page.tsx에서 params라는 props를 가져올 수 있었다!
즉, 전체 url이 필요하거나 쿼리 스트링이 필요하지 않다면 Hook을 가져올 필요 없이 params를 props에서 가져오도록 하면 된다.

레퍼런스

Next.js - useRouter
Next.js - usePathname
Next.js - useSearchParams
Stack Overflow - params

profile
For me better than yesterday

0개의 댓글