Next.jsの理解を深める!Chapter 4-5
Chapter 4
page.tsx is a special Next.js file that exports a React component, and it's required for the route to be accessible. In your application, you already have a page file: /app/page.tsx - this is the home page associated with the route /.
- page.tsxはReactコンポーネントをexport defaultしないといけないという制約がある。
そうすることによって、パスにアクセスできるようになる。(file-system routing)
By having a special name for page files, Next.js allows you to colocate UI components, test files, and other related code with your routes. Only the content inside the page file will be publicly accessible. For example, the /ui and /lib folders are colocated inside the /app folder along with your routes.
-
page.tsx
layout.tsx
loading.tsx
error.tsx
というNext.jsの名前を指定してる
ファイル名を使わなかったら自由にディレクトリとファイル作っていいということ。 - dashboardにのみ使用するコンポーネントがあったら以下の
foo.tsx
のように定義したり、
_componentsというディレクトリを作ってそこにまとめてコンポーネント配置してもいい。
(このようなcolocationの考え方が最近のReactには流行ってる)
One benefit of using layouts in Next.js is that on navigation, only the page components update while the layout won't re-render. This is called partial rendering:
-
layout.tsx
を使って共通化するとその部分は再レンダリングされない。
This is called a root layout and is required. Any UI you add to the root layout will be shared across all pages in your application. You can use the root layout to modify your <html> and <body> tags, and add metadata (you'll learn more about metadata in a later chapter).
- ルートレイアウトには基本
html
body
metadata
のみ。 - 全ページに適用されるため
header
追加したりごちゃごちゃしない方がいい。
import '@/app/ui/global.css';
import { inter } from '@/app/ui/fonts';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={`${inter.className} antialiased`}>{children}</body>
</html>
);
}
Chapter 5
Why optimize navigation?
To link between pages, you'd traditionally use the <a> HTML element. At the moment, the sidebar links use <a> elements, but notice what happens when you navigate between the home, invoices, and customers pages on your browser.
Did you see it?
There's a full page refresh on each page navigation!
- <a>タグ使用するとサーバー側にもリクエスト送ってリフレッシュされてしまう。
-
next/link
を使うべし。そしたらクライアント側のみのナビゲーションができる。 - <a>タグと同じように使用できる。
import {
UserGroupIcon,
HomeIcon,
DocumentDuplicateIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
// ...
export default function NavLinks() {
return (
<>
{links.map((link) => {
const LinkIcon = link.icon;
return (
<Link
key={link.name}
href={link.href}
className="flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3"
>
<LinkIcon className="w-6" />
<p className="hidden md:block">{link.name}</p>
</Link>
);
})}
</>
);
}
Automatic code-splitting and prefetching
To improve the navigation experience, Next.js automatically code splits your application by route segments. This is different from a traditional React SPA, where the browser loads all your application code on initial load.
Splitting code by routes means that pages become isolated. If a certain page throws an error, the rest of the application will still work.
Futhermore, in production, whenever <Link> components appear in the browser's viewport, Next.js automatically prefetches the code for the linked route in the background. By the time the user clicks the link, the code for the destination page will already be loaded in the background, and this is what makes the page transition near-instant!
- 本番環境なら
Link
コンポーネントがブラウザのビューポートに表示される度、リンク先のルートのコードをバックグラウンドで自動的にプリフェッチする。ユーザーがリンクをクリックするころには、リンク先ページのコードはすでにバックグラウンドで読み込まれている。
(静的なデータのみフェッチすると考える)
Pattern: Showing active links
A common UI pattern is to show an active link to indicate to the user what page they are currently on. To do this, you need to get the user's current path from the URL. Next.js provides a hook called usePathname() that you can use to check the path and implement this pattern.
Since usePathname() is a hook, you'll need to turn nav-links.tsx into a Client Component. Add React's "use client" directive to the top of the file, then import usePathname() from next/navigation:
- ページ遷移するとそのナビゲーションバーの色を変えるには
use client
とusePathname
を使ってパスを動的に取得する。
'use client';
import {
UserGroupIcon,
HomeIcon,
DocumentDuplicateIcon,
} from '@heroicons/react/24/outline';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import clsx from 'clsx';
// ...
export default function NavLinks() {
const pathname = usePathname();
return (
<>
{links.map((link) => {
const LinkIcon = link.icon;
return (
<Link
key={link.name}
href={link.href}
className={clsx(
'flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3',
{
'bg-sky-100 text-blue-600': pathname === link.href,
},
)}
>
<LinkIcon className="w-6" />
<p className="hidden md:block">{link.name}</p>
</Link>
);
})}
</>
);
}