ゼロから学ぶ React, Next.js⑦【React Foundations】Chapter 10, 11
公式チュートリアルはこちら
【Chapter 10】 サーバーコンポーネントとクライアントコンポーネント
サーバーコンポーネントとクライアントコンポーネントの仕組みを理解するには、2つの基本的なWeb概念に精通していると役立ちます。
サーバー環境とクライアント環境
Webアプリケーションのコンテキストでは:
- クライアントとは、ユーザーのデバイス上のブラウザのことで、アプリケーションコードをサーバーにリクエストします。そして、サーバーから受け取ったレスポンスを、ユーザーが操作できるインターフェイスに変換します。
- サーバーとは、アプリケーションコードを保存し、クライアントからのリクエストを受け取り、何らかの計算を行い、適切なレスポンスを送り返すデータセンターのコンピュータのことです。
各環境には、それぞれ独自の機能と制約があります。例えば、レンダリングとデータフェッチをサーバーに移動することで、クライアントに送信されるコードの量を減らすことができ、アプリケーションのパフォーマンスを向上させることができます。しかし、前述のように、UIをインタラクティブにするには、クライアント上でDOMを更新する必要があります。
そのため、サーバーとクライアント用に書くコードは、必ずしも同じではありません。特定の操作(データフェッチやユーザー状態の管理など)は、一方の環境の方が適しています。
ネットワーク境界
ネットワーク境界は、異なる環境を分離する概念上の線です。
Reactでは、コンポーネントツリーのどこにネットワーク境界を配置するかを選択します。例えば、サーバー上でデータをフェッチしてユーザーの投稿をレンダリングし(サーバーコンポーネントを使用)、各投稿のインタラクティブなLikeButton
をクライアント上でレンダリングする(クライアントコンポーネントを使用)ことができます。
同様に、サーバー上でレンダリングされ、ページ間で共有されるNav
コンポーネントを作成することができますが、リンクのアクティブ状態を表示したい場合は、クライアント上でLinks
のリストをレンダリングすることができます。
舞台裏では、コンポーネントは2つのモジュールグラフに分割されます。サーバーモジュールグラフ(またはツリー)には、サーバー上でレンダリングされるすべてのサーバーコンポーネントが含まれ、クライアントモジュールグラフ(またはツリー)には、すべてのクライアントコンポーネントが含まれます。
サーバーコンポーネントがレンダリングされた後、React Server Component Payload(RSC)と呼ばれる特殊なデータ形式がクライアントに送信されます。RSCペイロードには以下のものが含まれます。
- サーバーコンポーネントのレンダリング結果。
- クライアントコンポーネントをレンダリングする場所のプレースホルダー(または穴)と、そのJavaScriptファイルへの参照。
Reactはこの情報を使用して、サーバーコンポーネントとクライアントコンポーネントを統合し、クライアント上でDOMを更新します。
その仕組みを見てみましょう。
クライアントコンポーネントの使用
前の章で学んだように、Next.jsはデフォルトでサーバーコンポーネントを使用します。これは、アプリケーションのパフォーマンスを向上させるためであり、サーバーコンポーネントを採用するために追加の手順を踏む必要がないことを意味します。
ブラウザのエラーを見返すと、Next.jsはサーバーコンポーネント内でuseState
を使用しようとしていることを警告しています。これは、インタラクティブな「いいね」ボタンをクライアントコンポーネントに移動することで修正できます。
app
フォルダ内にlike-button.js
という新しいファイルを作成し、LikeButton
コンポーネントをエクスポートします。
+ export default function LikeButton() {}
page.js
から<button>
要素とhandleClick()
関数を新しいLikeButton
コンポーネントに移動します。
export default function LikeButton() {
+ function handleClick() {
+ setLikes(likes + 1);
+ }
+ return <button onClick={handleClick}>Like ({likes})</button>;
}
次に、likes
の状態とimport
を移動します。
+import { useState } from 'react';
export default function LikeButton() {
+ const [likes, setLikes] = useState(0);
function handleClick() {
setLikes(likes + 1);
}
return <button onClick={handleClick}>Like ({likes})</button>;
}
これで、LikeButton
をクライアントコンポーネントにするために、ファイルの先頭にReactの'use client'
ディレクティブを追加します。これは、Reactにコンポーネントをクライアントでレンダリングするように指示します。
+'use client';
import { useState } from 'react';
export default function LikeButton() {
const [likes, setLikes] = useState(0);
function handleClick() {
setLikes(likes + 1);
}
return <button onClick={handleClick}>Like ({likes})</button>;
}
page.js
ファイルに戻って、LikeButton
コンポーネントをページにインポートします。
+import LikeButton from './like-button';
function Header({ title }) {
return <h1>{title ? title : 'Default title'}</h1>;
}
export default function HomePage() {
const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
return (
<div>
<Header title="Develop. Preview. Ship." />
<ul>
{names.map((name) => (
<li key={name}>{name}</li>
))}
</ul>
+ <LikeButton />
</div>
);
}
両方のファイルを保存し、ブラウザでアプリを表示します。エラーがなくなったので、変更を加えて保存すると、ブラウザが自動的に更新されて変更が反映されるはずです。
この機能はFast Refreshと呼ばれています。編集内容をすぐにフィードバックしてくれるもので、Next.jsにはあらかじめ設定されています。
まとめ
まとめると、サーバー環境とクライアント環境、そしてそれぞれをいつ使用するかを学びました。また、Next.jsはパフォーマンスを向上させるためにデフォルトでReact Server Componentsを使用しており、UIの一部をインタラクティブにするためにClient Componentsをオプトインする方法も学びました。
追加の読み物
サーバーコンポーネントとクライアントコンポーネントについては、まだまだ学ぶべきことがたくさんあります。以下は追加のリソースです。
【Chapter 11】 次のステップ
Next.jsアプリケーションを作成おめでとうございます!
まとめると、ReactとNext.jsの基礎知識を探求し、シンプルなReactアプリケーションからNext.jsアプリケーションへの移行を行いました。
これからどうする?
Reactの学習を続ける
長年にわたって、開発者がReactを学ぶのを助けるために、多くのコース、ビデオ、記事が作成されてきました。学習スタイルに合ったリソースを推奨するのは難しいですが、非常に貴重なリファレンスの1つがReactのドキュメントで、トピックの練習に役立つインタラクティブなサンドボックスが含まれています。
ダッシュボードアプリを作ってNext.jsを学ぶ
ダッシュボードアプリを作成することで、Next.jsの学習を続けましょう。このコースでは、Next.jsの主要な機能を紹介し、より複雑なプロジェクトを構築することで実践的に学ぶことができます。
次の章
Discussion