Next.js를 통해 프로젝트를 진행하던 중에 NextRouter was not mounted.
에러가 발생했다.
ServerComponent에 useRouter
를 import하면서 발생한 에러이다.
공식 문서를 찾아보니 usePathname
과 useSearchParams
에 대한 내용이 있으니
본문에서 자세히 알아보자.
혹시나 ServerComponent가 뭐지? 싶다면 Next.js의 13 베타 버전에 대한 내용이니
여기서 잠깐 훑어보면 대충 짐작은 갈 것이다.
=> [Next.js] Server/Client Component
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
Thepathname
string has been removed and is replaced byusePathname()
Thequery
object has been removed and is replaced byuseSearchParams()
router.events
is not currently supported. See below.
요약하자면
이제 문자열
useRouter().pathname
과 객체useRouter().query
는 마이그레이션 됐다 ㅅㄱ
그렇다. 이제 더 이상 params 값을 호출하기 위해 useRouter
훅을 가져오는 것이 아니라
usePathname
과 useSearchParams
훅을 가져다가 사용하면 된다.
현재 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}</>
}
URL | returned value |
---|---|
/ | '/' |
/dashboard | '/dashboard' |
/dashboard?v=2 | /dashboard' |
/blog/hello-world | /blog/hello-world' |
쿼리 스트링을 하기 위한 훅으로 아래 예시와 함께 살펴보자.
'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 키의 존재 여부를 확인할 수 있다.
그렇다면 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
useSearchParams나 Pathname은 CSR에서만 사용할 수 있는건가요? SSR 단계에서 사용할 수 있는 함수는 없을까요 ?