Next.js 13での主な新機能
Next.jsはバージョンアップされるたびに新しい機能が次々に追加されています。
今回はNext.js 13の中からRoute segmentsとServer Componentsの新機能に絞って学んだことのアウトプットの記事です。
Next.js 13での主な新機能
1.Route segments ←今回の記事のアウトプット
2.Server Components ←今回の記事のアウトプット
3.Streaming
4.Layouts
参考・引用しているのはこちらのUdemyの動画です。Next.js13の機能をハンズオンで学べて分かりやすく、おすすめです!
Route segments
appディレクトリの中にはフォルダを階層状に作っていくことができ、そのフォルダ1つ1つがセグメントに対応しています。各セグメントはURLパスでアクセスすることができます。
公式ドキュメント より引用
アプリケーション全体が1つのツリー構造になっていて、そこから分岐しているそれぞれのかたまりのことをサブツリーと呼んでいます。
各セグメントを表すフォルダの中にはファイルを作成することができ、appディレクトリの中ではあらかじめ決められた特殊なファイル名というものが存在します。
それがpage.tsx、layout.tsx、error.tsx、loading.tsx、あとはテンプレートとHeadというものがあります。
<Layout>
<ErrorBoundary fallback={<Error />}>
<Suspense fallback={<Loading />}>
<Page />
</Suspense>
</ErrorBoundary>
</Layout>
page.tsxは対象のセグメントのユーザーインターフェースを記述するファイルコンポーネントになっています。
layout.tsxはページのコンポーネントに対するレイアウトに対応しています。
loading.tsxを追加するとページのコンポーネントをラップする形で1つサスペンスが自動的に付与され、fallbackのスケルトンの内容をloading.tsxのファイルな中でカスタマイズしていくことができます。
さらに、error.tsxのセグメントのフォルダの中に追加していくと、Next.jsによってサスペンスをラップする形でエラーバウンダリが自動的に追加され、fallbackで表示させるエラーの内容をカスタマイズしていくことができます。
appディレクトリの中は、すべてのコンポーネントがデフォルトでサーバーコンポーネントと認識されています。
head.tsxの廃止
Next.js 13.4 以降では、App Routerがstable版となり、beta版で存在していた head.tsxが廃止になりました。
titleの値などは、export const metadata
を使用しlayout.tsxに設定します。
import NavBar from './components/nav-bar'
import './globals.css'
export const metadata = {
title: 'Nextjs App',
description: 'Generated by create next app',
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html>
<body>
<NavBar />
{children}
</body>
</html>
)
}
Server Components
Next.js 13では、目玉機能としてServer Componentsが導入されました。
Server Components
The app/ directory introduces support for React's new Server Components architecture. Server and Client Components use the server and the client each for what they're best at - allowing you to build fast, highly-interactive apps with a single programming model that provides a great developer experience.
With Server Components, we're laying the foundations to build complex interfaces while reducing the amount of JavaScript sent to the client, enabling faster initial page loads.
When a route is loaded, the Next.js and React runtime will be loaded, which is cacheable and predictable in size. This runtime does not increase in size as your application grows. Further, the runtime is asynchronously loaded, enabling your HTML from the server to be progressively enhanced on the client.
翻訳
app/ディレクトリは、Reactの新しいServer Componentsアーキテクチャのサポートを導入しています。Server ComponentsとClient Componentsは、サーバーとクライアントをそれぞれ得意とする用途に使用します - 素晴らしい開発者体験を提供する単一のプログラミングモデルで、高速で高度にインタラクティブなアプリを構築できます。
Server Componentsでは、クライアントに送信されるJavaScriptの量を減らしながら、複雑なインターフェイスを構築するための基礎を築き、より高速な初期ページロードを可能にします。
ルートがロードされると、Next.jsとReactのランタイムがロードされます。このランタイムは、アプリケーションが大きくなってもサイズが大きくなることはありません。さらに、ランタイムは非同期にロードされるため、サーバーからのHTMLをクライアントで徐々に拡張することができます。
Server ComponentsとClient Componentの違い
Server Components | Client Component | |
---|---|---|
① | サーバーでRenderingされる (= Javascriptはクライアントに送られない) | ブラウザでJavascriptが実行される |
② | Data fetchにasync/awaitを使用できる | Data fetchにasync/awaitが使用できない(=useState,useEffect,SWR,React-queryを使用する必要がある) |
③ | Secure keyを使用可能 | Secure keyを使用不可 |
④ | Brower APIは使用不可 | Brower APIは使用可能 |
⑤ | useState,useEffect等は使用不可 | useState,useEffectを使用可能 |
⑥ | Event listener(onClick等) は使用不可 | Event listener(onClick等) を使用可能 |
サーバーコンポーネントの特徴
①サーバーコンポーネントはサーバーサイドでJavascriptが実行されてレンダリングされるため、サーバーコンポーネントに含まれているJavascriptやnpmパッケージはクライアントに送られないメリットがあります。
②コンポーネントレベルでasync/awaitを使用できるため、Data fetchを簡単に記述することができます。
③サーバーコンポーネントの方ではシークレットな環境変数を読み込むこと(envファイル等)ができます。
④一方で、サーバーで実行されるため、ブラウザ特有のAPIなどは実行することができません。
⑤⑥ React特有のuseState,useContext,useEffectやonClick,onSubmitで使われるイベントリスナーはサーバーコンポーネントで使用することはできません。
クライアントコンポーネントの特徴
①ブラウザでJavascriptが実行されます。
②,③データフェッチをする場合は、サーバーコンポーネントのようにコンポーネントの階層でasync functionを使用することができないので、useEffect,ReactQuery,SWR,use(新しいhooks)を使用する必要があります。
④完全なシークレットキーをブラウザで使用することはできません。
⑤⑥ useState,イベントリスナーは全て使用することができます。
ファイルをクライアントコンポーネントに設定したい場合は、1行目に'use client'
と記述します。
インポートのルール
サーバーコンポーネントからクライアントコンポーネントをインポートすることはできますが、クライアントコンポーネントの方からサーバーコンポーネントをインポートして使用することはできません。
// NG
'use client'
import ServerComponent from './ServerComponent'
~省略~
return(
<>
<ServerComponent />
</>
)
例外は、クライアントコンポーネントのチルドレンとしてサーバーコンポーネントを渡すことはできます。
// OK
'use client'
import ClientComponent from './ClientComponent'
import ServerComponent from './ServerComponent'
~省略~
return(
<ClientComponent>
<ServerComponent />
</ClientComponent>
)
上記の例外では、Reactがサーバーコンポーネントを事前にサーバーサイドをレンダリングしておかなければならないということを認識します。
クライアントサイドでクライアントコンポーネントが実行されるときにチルドレンのところにすでに実行されているサーバーコンポーネントのレンダリング結果がpropsで渡されることによって、クライアントコンポーネントで実行することができます。
参考