この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
Next.js Conf 2022でNext.js 13の発表がありました。BlogなかでNext.js13の新機能まとまっていたので引用。
- app/ Directory (beta): Easier, faster, less client JS.
- Layouts
- React Server Components
- Streaming
- Turbopack (alpha): Up to 700x faster Rust-based Webpack replacement.
- New next/image (stable): Faster with native browser lazy loading.
- New @next/font (beta): Automatic self-hosted fonts with zero layout shift.
- Improved next/link: Simplified API with automatic
<a>
.
かなり、魅力的な機能がたくさんです。
ディレクトリ構造がそのままパスルーティングされますが、Next.js 13ではReact18になり、SuspenseをつかったData FetchingやRenderingがいい感じにできるようになっているようです。
早速やってみます。
やってみた
今回は以下の2つの機能を試してみました。
今回のサンプルはこちらになります
サンプル作成
既存をマイグレーションせずに新規で作ります。
$ npx create-next-app nextjs13-sample --ts --use-npm
新規作成で、すでにNext.js 13になってるようです。
ただ、app/ Directory (beta)
はbetaなのでnext.config.jsで有効化する必要があります
next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
experimental: {
appDir: true,
},
}
module.exports = nextConfig
appディレクトリに移す
新規作成時は従来通りの./pages
でルーティングが設定されてるので、appを有効化しても、pagesが存在するとエラーになってしまいます。ばっさり削除します。
appディレクトリを作成します。
$ rm -rf pages
$ mkdir app
いままでpagesには基本にはpageファイルだけで、アプリで共通の設定が_documentや_appなどでしたが、それが各ページ毎におけるようになったイメージです。
- page.tsx: ページで読みこまれる(いままでpagesにおいていたファイル相当)
- layout.tsx: ページ毎のレイアウト。
- loading.tsx: Suspenseが発生した時のローディングView
- error.tsx: Suspenseでエラーが発生したきのエラーView
- template.tsx: レイアウトにてるけどちょっと違う。レイアウトは状態を維持するけどテンプレートは常に新しいインスタンスされ状態の引き継がない。
- head.tsx:
Head
の設定
いままではindex.jsを読み込まれるようになってましたが、page.jsを読み込まれるようになります。
サンプルとしてGitHubのUsersを表示するページを作ります。
layoutを作成
基礎的なHtmlの雛形のlayoutで作成。
"
import { FC, PropsWithChildren } from "react";
const RootLayout: FC<PropsWithChildren> = ({ children }) => {
return (
<html lang="en">
<head>
<title>Next.js</title>
</head>
<body>{children}</body>
</html>
);
};
export default RootLayout;
loadingを作成
GitHub Users APIをfetchでSuspenseで読み込み、そのときのローディングViewを作成
"
export default function Loading() {
return <div>Loading...</div>;
}
pageを作成
Reactのuseを使ってデータを表示します。(あれもうuseつかえるのか。。。)
"
import { use } from "react";
type User = {
id: number;
login: string;
};
const fetchUsers: () => Promise<User[]> = async () => {
const res = await fetch("https://api.github.com/users");
return res.json();
};
export default function Page() {
const users = use(fetchUsers());
return (
<div>
<h1>GitHub Users!</h1>
<div>
{users.map((user) => {
return (
<div key={user.id}>
{user.id}: {user.login}
</div>
);
})}
</div>
</div>
);
}
実際に動かす
$ npm run dev
まとめ
React18のSuspenseがやはり起爆剤で、色々追加/変更がありますが、かなり嬉しい変化だと思っています。
Rustの影響でまた新たなビルドツールTurbopackもでてきましたし、変化が激しい時期がまだまだ続きそうですね。