https://zenn.dev/sora_kumo/articles/46a87f1bde207c
React18.3以降の新機能useを使うと、throw promise
とデータの取得部分の処理が簡略化出来ます。そしてuseを使ったコンポーネントは非同期中の状態を受け取るためSuspenseとセットで使われることが想定されます。しかしNext.jsで使う場合、必ずしもセットにしなくても動作します。その場合は異なった挙動をするので、違いを確認するためNext.js 13の新機能app/ Directory (beta)
を使って出力結果を検証します。ちなみにReact 18.2やNext.js 12以前のバージョンでも同様の動作をします。最新版で固めたのは、新機能が非同期に最適化されているため、コードの記述量が減るからです。
TypeScriptや@types/nodeは自動で入ります。
// @ts-check
/**
* @type { import("next").NextConfig}
*/
const config = {
reactStrictMode: true,
experimental: {
appDir: true
},
};
module.exports = config;
ちなみにStreaming-SSRをするためにruntime: "experimental-edge"
の設定は不要です。appフォルダの機能を使うと自動的にStreamingが有効になります。
動作確認用リンクです。完全にページ遷移する必要があるのでaタグでリンクを張っています。
const Page = () => {
return (
<>
<div>
<a href="<https://github.com/SoraKumo001/next-layouts-test>">Source code</a>
</div>
<hr />
<div>
<a href="/suspense">Suspense有り</a>
</div>
<div>
<a href="/nosuspense">Suspense無し</a>
</div>
</>
);
};
export default Page;
1秒のウエイトが入った状態で東京の天気予報を取得します。 Streamingが有効になっているので初期状態でLoadingが表示され、その後、天気予報に切り替わります。
import React, { Suspense, use } from "react";
export interface WeatherType {
publishingOffice: string;
reportDatetime: string;
targetArea: string;
headlineText: string;
text: string;
}
const fetchWeather = (id: number): Promise<WeatherType> =>
fetch(`https://www.jma.go.jp/bosai/forecast/data/overview_forecast/${id}.json`)
.then((r) => r.json())
.then(
//ウエイト追加
(r) => new Promise((resolve) => setTimeout(() => resolve(r), 1000))
);
const Weather = () => {
//Reactの新機能useでデータを取り出す
const weather = use(fetchWeather(130000));
return (
<div>
<h1>{weather.targetArea}</h1>
<div>
{new Date(weather.reportDatetime).toLocaleString('ja-JP', {
timeZone: 'JST',
year: 'numeric',
month: 'narrow',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
})}
</div>
<div>{weather.headlineText}</div>
<pre>{weather.text}</pre>
</div>
);
};
const Page = () => {
return (
<Suspense fallback='Loading'>
<Weather />
</Suspense>
);
};
export default Page;
1秒のウエイトが入った状態で東京の天気予報を取得します。 こちらはSuspenseを入れていません。 Suspenseが無い場合はStreamingが行われず、データが出そろうまで待機状態になります。