Next의 공식문서에서 Next의 함수를 보면, Server Components에서 사용되는 functions(함수)
와 Client Components에서 사용되는 hooks(훅)
으로 분리되어 있는 것 같다.
redirect 함수를 사용하면 사용자른 임의의 URL로 리다이렉트 시킬 수 있다.
예시
import { redirect } from 'next/navigation'
async function fetchTeam(id) {
const res = await fetch('https://...')
if (!res.ok) return undefined
return res.json()
}
export default async function Profile({ params }) {
const team = await fetchTeam(params.id)
if (!team) {
redirect('/login')
}
// ...
}
서버에서 path에 정의된 경로에 있는 요청들의 캐시를 전부 revalidate한다.
import { revalidatePath } from 'next/cache'
revalidatePath('/blog/post-1')
서버에서 revalidateTag 함수를 사용하여 특정 태그를 가진 데이터의 캐시를 revalidate한다.
예시
'use server'
import { revalidateTag } from 'next/cache'
export default async function submit() {
await addPost()
revalidateTag('posts')
}
현재 URL 주소의 경로이름을 가져온다.
예시
'use client'
import { usePathname, useSearchParams } from 'next/navigation'
function ExampleClientComponent() {
const pathname = usePathname()
useEffect(() => {
// Do something here...
}, [pathname])
}
현재 URL 주소의 쿼리스트링 값을 가져온다.
searchParams.get(name: string)
: name에 해당하는 값을 가져온다.searchParams.has(name: string)
: name에 해당하는 값이 존재하는지 확인한다.예시
'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}</>
}
useRouter 훅을 사용하면 사용자의 라우트를 변경할 수 있다.
router.push(href: string, { scroll: boolean })
: 브라우저의 history 스택에 새 항목을 추가하고 이동한다.router.replace(href: string, { scroll: boolean })
: 브라우저의 history 스택에 새 항목을 추가하지 않고 이동한다.router.refresh()
: 현재 경로를 새로 고침한다. 서버에 새 요청을 보내고, 데이터 요청을 다시 가져오고, 서버 구성 요소를 다시 렌더링한다.router.prefetch(href: string)
: 더 빠른 클라이언트측 전환을 위해 제공된 경로를 미리 로드해준다.router.back()
: 이전 페이지로 이동한다.router.forward()
: 다음 페이지로 이동한다.router.push()와 router.replace()의 차이
예를 들어, 메인페이지에서 /login 경로로 이동할 때, login 페이지의 useRouter()을 통해 /new/login으로 이동한다 생각해보자.
각자의 메서드는 다음과 같이 작동한다.
router.push()
: example.com → example.com/login → example.com/new/loginrouter.replace()
: example.com → (example.com/login) → example.com/new/login이렇게 보면 둘이 무슨 차이인지 이해가 안될 수 있다. router.replace()
같은 경우 논리적으로는 /login 경로를 거친다. 하지만 /new/login에서 뒤로가기를 시도하면 example.com으로 이동된다.
반면에, router.push()
는 /login 경로를 거친 후 /new/login으로 이동하기에 뒤로가기를 시도하면 example.com/login으로 이동한다.
예시
'use client'
import { useRouter } from 'next/navigation'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push('/dashboard')}>
Dashboard
</button>
)
}
useSelectedLayoutSegment 훅을 사용하면 이 훅을 사용한 레이아웃 경로의 한 단계 아래의 경로를 읽어온다
이때 리턴되는 값은 string이다.
예시
// app/layout.js
'use client'
import { useSelectedLayoutSegment } from 'next/navigation'
export default function ExampleClientComponent() {
const segment = useSelectedLayoutSegment()
return <p>Active segment: {segment}</p>
}
예를 들어, app/layout.js에 위와 같이 작성했고 URL은 /dashboard로 접속한다면 segment는 "dashboard"가 된다.
useSelectedLayoutSegmnet와 유사하나, 이 훅이 사용한 레이아웃 경로의 아래 모든 경로를 다 읽어온다.
이때 리턴되는 값은 useSelectLayoutSegment와 달리 배열로 리턴된다.
예시
// app/layout.js
'use client'
import { useSelectedLayoutSegments } from 'next/navigation'
export default function ExampleClientComponent() {
const segments = useSelectedLayoutSegments()
return (
<ul>
{segments.map((segment, index) => (
<li key={index}>{segment}</li>
))}
</ul>
)
}
예를 들어, app/layout.js에 위와 같이 작성되어 있고 URL은 /dashboard/settings로 접속한다면, segments는 [dashboard, settings]이 된다.