Next.js 15์์๋ App Router๊ฐ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํ๋ ์๋ก์ด Navigation Hook๋ค์ด ์๋ค. ์ด Hook๋ค์ React ์ฑ์ ๋ผ์ฐํ ์ ์ข ๋ ํธ๋ฆฌํ๊ณ , ์ง๊ด์ ์ผ๋ก ๋ง๋ค์ด์ค๋ค. ํนํ useRouter, usePathname, useSearchParams์ ๊ฐ์ Hook๋ค์ ๋ค๋น๊ฒ์ด์ ๊ณผ ๊ด๋ จ๋ ์์ ์ ์์ฝ๊ฒ ํด์ค๋ค.
useRouter โ ๋ผ์ฐํ ๊ด๋ จ ์ ๋ณด์ ํจ์ ์ ๊ณต
useRouter๋ ํ์ฌ ๋ผ์ฐํฐ์ ๊ด๋ จ๋ ์ ๋ณด์ ํจ์๋ค์ ์ ๊ณตํ๋ค. ํ์ด์ง ์ด๋์ด๋ ๋ผ์ฐํ ์ํ๋ฅผ ๊ด๋ฆฌํ ๋ ์ ์ฉํ๋ค. App Router์์๋ useRouter๋ก router.push, router.replace ๋ฑ์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๊ณ , ํ์ฌ URL ์ ๋ณด๋ฅผ ์ป์ ์ ์๋ค.
import { useRouter } from 'next/navigation';
export default function MyPage() {
const router = useRouter();
const handleClick = () => {
router.push('/next-page');
};
return (
<div>
<button onClick={handleClick}>Go to Next Page</button>
</div>
);
}
useRouter๋ ํ์ด์ง ์ด๋์ ์ฝ๊ฒ ํ ์ ์๊ฒ ๋์์ค๋ค. ๋ํ, ํ์ด์ง์ query๋ path, search params ๋ฑ๋ ๋ฐ๋ก ๊ฐ์ ธ์ฌ ์ ์๋ค.
usePathname โ ํ์ฌ ๊ฒฝ๋ก ์ป๊ธฐ
usePathname์ ํ์ฌ ๊ฒฝ๋ก๋ฅผ ๊ฐ์ ธ์ฌ ๋ ์ ์ฉํ Hook์ด๋ค. ํ์ด์ง์ ๊ฒฝ๋ก๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ํ ๋ ์ฃผ๋ก ์ฌ์ฉ๋๋ค.
import { usePathname } from 'next/navigation';
export default function Navigation() {
const pathname = usePathname();
return (
<div>
<h1>ํ์ฌ ๊ฒฝ๋ก: {pathname}</h1>
</div>
);
}
useSearchParams โ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ ๊ด๋ฆฌ
useSearchParams๋ ํ์ฌ URL์์ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฝ๊ฒ ๊ฐ์ ธ์ค๊ณ ๋ณ๊ฒฝํ ์ ์๊ฒ ํด์ฃผ๋ Hook์ด๋ค. ์ด๋ฅผ ํตํด URL์ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ฅผ ์ง์ ์กฐ์ํ๊ฑฐ๋ ์ํ์ ๋ง๊ฒ URL์ ์ ๋ฐ์ดํธํ ์ ์๋ค.
import { useSearchParams } from 'next/navigation';
export default function SearchPage() {
const searchParams = useSearchParams();
const searchQuery = searchParams.get('query');
return (
<div>
<h1>๊ฒ์์ด: {searchQuery}</h1>
</div>
);
}
useSearchParams๋ URL์ ์๋ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฝ๊ฒ ์ฒ๋ฆฌํ ์ ์๊ฒ ๋์์ค๋ค. ์๋ฅผ ๋ค์ด, ๊ฒ์ ํ์ด์ง์์ ์ฌ์ฉ์๊ฐ ๊ฒ์์ด๋ฅผ ์ ๋ ฅํ ๋ URL์ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ฅผ ์ ๋ฐ์ดํธํ๊ณ , ๊ทธ ๊ฐ์ ์ฝ์ด์์ ์ ์ ํ ์ฒ๋ฆฌํ ์ ์๋ค.
๊ทธ๋ผ Page Router์์๋ ์ด๋ป๊ฒ ์ฐ๋?
Page Router์์๋ next/navigation ๋์ next/router ๋ฅผ ์ฌ์ฉํ๋ค. next/navigation์ useRouter ๋ App Router์์๋ง ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, Page Router์์๋ next/router ์์ ์ ๊ณตํ๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํด ํ์ด์ง๋ฅผ ์ด๋์ํค๊ณ , ๊ฒฝ๋ก๋ฅผ ๊ด๋ฆฌํด์ผ ํ๋ค. next/router๋ router.push, router.replace, router.query ๋ฑ์ ์ ๊ณตํ๋ฉฐ, ํ์ด์ง์ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ ๊ฒฝ๋ก ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐ ์ฌ์ฉ๋๋ค.
import { useRouter } from 'next/router';
export default function MyPage() {
const router = useRouter();
// ํ์ฌ ํ์ด์ง์ ๊ฒฝ๋ก๋ฅผ ๊ฐ์ ธ์ด
const currentPath = router.pathname;
// ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ฅผ ๊ฐ์ ธ์ด
const query = router.query;
// ๋ผ์ฐํธ ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ์ ธ์ด
const { id } = router.query;
const handleClick = () => {
router.push('/next-page');
};
return (
<div>
<p>ํ์ฌ ๊ฒฝ๋ก: {currentPath}</p>
<p>์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ: {JSON.stringify(query)}</p>
<button onClick={handleClick}>Go to Next Page</button>
</div>
);
}
์ ๋ฆฌ
| Hook | ์ธ์ ์ฐ๋ | ํน์ง |
|---|---|---|
| useRouter | App Router์์ ํ์ด์ง ์ด๋, ๋ผ์ฐํ ์ํ ๊ด๋ฆฌ ์ | ํ์ด์ง ์ด๋๊ณผ ๋ผ์ฐํ ๊ด๋ จ ์ ๋ณด๋ฅผ ์ ๊ณต |
| usePathname | ํ์ฌ ๊ฒฝ๋ก๋ฅผ ๊ฐ์ ธ์ฌ ๋ | ํ์ฌ ํ์ด์ง์ ๊ฒฝ๋ก๋ฅผ ๋ฐํ |
| useSearchParams | ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฝ๊ฒ ๊ฐ์ ธ์ฌ ๋ | URL์ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ฅผ ๊ด๋ฆฌ |
| next/router | Page Router์์ ๋ผ์ฐํ ๊ด๋ จ ์์ ์ | ํ์ด์ง ์ด๋, ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ, ๊ฒฝ๋ก ์ ๋ณด ์ ๊ณต |
๋ค์ ํํธ์์๋
useSelectedLayoutSegment, useFormState, useFormStatus์ ๊ฐ์ ์๋ก์ด App Router ๊ด๋ จ ํ ์ ์ดํด๋ณด๋ฉฐ, ๊ทธ ์ฌ์ฉ๋ฒ๊ณผ ์ค๋ฌด์์ ์ด๋ป๊ฒ ํ์ฉํ ์ ์๋์ง์ ๋ํด ๋ค๋ฃฐ ์์ ์ด๋ค. React์ Next.js์ ์ต์ ๊ธฐ๋ฅ๋ค์ ์ค๋ฌด์ ์ด๋ป๊ฒ ์ ์ฉํ ์ ์์์ง ๊ณ ๋ฏผํด๋ณด๊ณ , ๊ฐ ํ ๋ค์ ํน์ฑ์ ์ ํ์ฉํ๋ ๋ฐฉ๋ฒ์ ์ ๋ฆฌํ ์์ ์ด๋ค.