Next.js公式のReactチュートリアルをやってみる

初めに

Next.jsでは公式がReactの基礎というチュートリアルを公開しています。Next.jsを学ぶためにはJavaScript、React、Web開発の概念に関する知識が必要となるため、Next.jsの開発を始める前にReactの基本を改めて復習するとともに記録します。

筆者はNext.jsを学習することを目的としているため、そのほかのライブラリも含めて環境構築しています。
参考までに手順をまとめましたのでよかったらどうぞ。

TypeScript+Next.js+Vite+VitestでWebアプリを開発する【環境構築編】 TypeScript+Next.js+Vite+VitestでWebアプリを開発する【環境構築編】

Reactとは

ウェブブラウザで使用するUIの開発を簡単にするためのJavaScriptライブラリです。
このライブラリにはUIを構築するための関数が用意されていて、開発者が関数を適宜使用することで効率的に開発を進めることができます。

Next.jsとは

Reactの機能を拡張したフレームワークです。サーバーサイドレンダリング(SSR)と静的サイト生成(SSG)とクライアントサイドレンダリング(CSR)をサポートしているため、サイトの表示を高速化することができるなど様々なメリットがあります。

Web開発の基本

UIのレンダリング

ユーザーがウェブサイトにアクセスするとサーバーはブラウザに対してHTMLファイルを返します。

index.html
<html>
    <body>
        <div>
            <h1>チーム</h1>
            <ul>
                <li>田中太郎</li>
                <li>山田花子</li>
                <li>佐藤一</li>
            </ul>
            <button>Like (0)</button>
        </div>
    </body>
</html>

DOMについて

DOMとはDocument Object Modelの略称で、HTMLの要素をツリー構造で表したデータモデルのことです。
DOMメソッドを使うことで選択、追加、削除、更新などでDOMを操作することができます。

例えば上記のようなHTMLファイルが返された場合、DOMは以下のような構成になります。

DOMの操作

では早速DOMを操作してh1タグを追加してみましょう。

まずは以下のコードでindex.htmlファイルを作成しましょう。
このコードは追加先をターゲットとして設定できるように、divタグにappという一意なIDを付与しています。
また、今回はHTMLファイル内でJavaScript を実行するためにscriptタグを用意しています。

index.html
<html>
  <body>
    <div id="app"></div>
    <script type="text/javascript"></script>
  </body>
</html>

早速DOMメソッドを使用し、追加先のターゲットを選択しましょう。IDを識別して要素を取得するので使用するメソッドはgetElementById()を使用します。

index.html
<html>
  <body>
    <div id="app"></div>
    <script type="text/javascript">
      const app = document.getElementById('app');
    </script>
  </body>
</html>

引き続きh1タグの追加処理を実装していきます。

index.html
<html>
  <body>
    <div id="app"></div>
    <script type="text/javascript">
      // 'app'というIDを持つdivの要素を取得する
      const app = document.getElementById('app');
 
      // H1の要素を作成
      const header = document.createElement('h1');
 
      // H1要素に新しいテキストのノードを作成する
      const text = 'Develop. Preview. Ship.';
      const headerContent = document.createTextNode(text);
 
      // テキストのノードをH1要素に追加する
      header.appendChild(headerContent);
 
      // H1要素をdivの中に配置する
      app.appendChild(header);
    </script>
  </body>
</html>

作成したHTMLファイルを開いてみましょう。「Develop. Preview. Ship.」という文字列が表示されていれば、DOMメソッドでの追加処理は成功です。

DOM操作の面倒さ

先ほどはDOMの操作によってh1タグを追加することができました。しかし、JavaScriptを使用してDOMを更新するのはいくつかステップが必要で少し冗長です。そこで「○○を見せたい」と一言で表して、DOMの操作をライブラリに任せることができればどうでしょうか。Reactは人気のある宣言型ライブラリでUIを構築するのに使えます。

React

Reactを使用するためにはunpkg.comという外部サイトから、2種類のReactスクリプトを読み込む必要があります。

名称概要
reactReactのコアライブラリ
react-domReactのDOM操作用ライブラリ
読み込むライブラリ

では早速以前作成したコードのDOM操作処理を、Reactを使用する方法に変更してみましょう。
index.htmlを以下のように変更していきます。

index.html
<html>
  <body>
    <div id="app"></div>

    <!-- React Scripts -->
    <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>

    <script>
      // 'app'というIDを持つdivの要素を取得する
      const app = document.getElementById('app');

      // app要素をターゲットにしてReact Componentsを表示するルートを作成
      const root = ReactDOM.createRoot(app);

      // ReactのコードをDOMにレンダリングする
      root.render(<h1>Develop. Preview. Ship.</h1>);
    </script>
  </body>
</html>

上記のコードでHTMLファイルを開くと構文エラーが発生しています。
原因はこちらのコード。
root.render(<h1>Develop. Preview. Ship.</h1>);

HTMLのscrpitタグ内ではJavaScriptの構文で書く必要があります。
scriptタグの中では<h1>...<h1/>のような構文はないため、エラーになっているのです。
このフォーマットのはJSXと呼ばれるフォーマットであるため、以下の様にこのスクリプトは「JSXで書いています」ということを明記しておかなければなりません。
<script type="text/jsx">

JSXとは

JavaScript XMLの略称で呼ばれる、JavaScriptの拡張構文です。HTMLのような構文でUIを記述できるため、複数のフレームワークに利用されています。

ブラウザはJSXを理解できないため、JSXからJavaScriptに変換する必要があります。
通常は、BabelなどのJavaScriptコンパイラを使用して変換します。

Babelを使用するには

Babelを使用するためには、以下のコードを追加してReactと同様にスクリプトを読み込む必要があります。
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

index.html
<html>
  <body>
    <div id="app"></div>

    <!-- React Scripts -->
    <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>

    <!-- Babel Script -->
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    
    <script type="text/jsx">
      // 'app'というIDを持つdivの要素を取得する
      const app = document.getElementById("app");

      // app要素をターゲットにする
      const root = ReactDOM.createRoot(app);

      // ReactのコードをDOMにレンダリングする
      root.render(<h1>Develop. Preview. Ship.</h1>);
    </script>
  </body>
</html>

ブラウザでHTMLファイルを開いて確認すると、ページにはDevelop. Preview. Ship.と表示され、開発者ツールでは構文エラーがなくなっているはずです。

ここで元のコードと比較してみましょう。

index.html
<script type="text/javascript">
  const app = document.getElementById('app');
  const header = document.createElement('h1');
  const text = 'Develop. Preview. Ship.';
  const headerContent = document.createTextNode(text);
  header.appendChild(headerContent);
  app.appendChild(header);
</script>
index.htmlq
<script type="text/jsx">
  const domNode = document.getElementById("app")
  const root = ReactDOM.createRoot(domNode);
  root.render(<h1>Develop. Preview. Ship.</h1>);
</script>

6行から3行になって半分もコードを削減することができましたね。
このように面倒な手順をReactが一気に省略してくれます。

Components(コンポーネント)

ReactのUIはComponentという単位で分解することができます。コンポーネントは再利用可能でレゴブロックのようなものです。組み合わせることで大きな構造物を組み立てることができ、UIを更新する場合は特定のコンポーネントを更新する必要があります。

このようなメディアコンポーネントでもさらに細分化すると以下のコンポーネントで構成されています。

この性質により、アプリケーションの他の処理に変更を加えずに追加・更新・削除ができるので、保守性に優れるのがReactコンポーネントのメリットです。

Componentsの作り方

ReactではComponentsをUI要素を返す関数として作成する必要があります。scriptタグの中にheaderという関数を作成しましょう。関数の中でもJSXを利用することができます。

index.html
<script type="text/jsx">
  const app = document.getElementById("app")
 
  function header() {
  }
 
  const root = ReactDOM.createRoot(app);
  root.render(<h1>Develop. Preview. Ship.</h1>);
</script>

まずは単純にroot.renderで直接入力していたJSXをheader()に移動しましょう。

index.html
<script type="text/jsx">
  const app = document.getElementById("app")
 
  function header() {
     return (<h1>Develop. Preview. Ship.</h1>);
  }
 
  const root = ReactDOM.createRoot(app);
  root.render(header);
</script>

ブラウザで確認してみるとエラーが出ていますので、二点ほど修正を加えます。

一つ目はJavaScriptの関数と区別するためにReactの関数はアッパーキャメルケースで関数名を宣言する必要があります。
二つ目はReactコンポーネントはHTMLタグと同じように角括弧で囲んで使用する必要があります。

以下が修正後のコードになります。

index.html
function Header() {
  return <h1>Develop. Preview. Ship.</h1>;
}
 
const root = ReactDOM.createRoot(app);
root.render(<Header />);

もう一度ブラウザで確認すると、エラーが消えて正常に表示できたことを確認できます。

コンポーネントのネスト

HTML要素と同じよにReactコンポーネントも入れ子にすることができます。
それではHomePageというコンポーネントを作成してみましょう。

index.html
function Header() {
  return <h1>Develop. Preview. Ship.</h1>;
}
 
function HomePage() {
  return (
    <div>
      {/* Headerコンポーネントをネストさせる */}
      <Header />
    </div>
  );
}
 
const root = ReactDOM.createRoot(app);
root.render(<HomePage />);

コンポーネントツリー

コンポーネントをネストし続けることで以下の様なコンポーネントツリーを形作ることができます。

これは一例ですが、トップレベルのHomePageコンポーネントは、Header、Article、Footerコンポーネントを、 それらの各コンポーネントは順番にそれ自身の子コンポーネントなどを持つことができます。 例えば、Headerコンポーネントには、Logo、Title、Navigationコンポーネントを含めることができます。 このモジュール形式により、アプリ内のさまざまな場所でコンポーネントを再利用することができます。

Props(小道具)

現時点ではHeaderコンポーネントを使用すると、まったく同じ内容が表示されます。
ですが、違うテキストを渡したい場合や、動的に内容はこのままでは利用できません。

通常のHTML要素には属性があり、その属性を使って要素の動作を変更する情報を渡すことができます。例えば、img要素のsrc属性を変更すると、表示される画像が変わります。aタグのhref属性を変更すると、リンク先が変わります。

Reactでも情報を属性として渡すことができます。これをReactではPropsと呼びます。
PropsはJavaScriptの関数と同様に設計することができ、親コンポーネントから子コンポーネントに渡すことができます。

Propsの使い方

それではHeaderで表示する内容をPropsで変更できるようにしてみましょう。HTML属性を渡すようにHeaderコンポーネントにtitleというカスタムプロパティを渡すことができます。console.log()で出力されたオブジェクトのプロパティを見るとtitleという属性を持っていることがわかります。

index.html
function HomePage() {
  return (
    <div>
      <Header title="React" />
    </div>
  );
}
index.html
function Header(props) {
  console.log(props); // { title: "React" }
  return <h1>Develop. Preview. Ship.</h1>;
}

propsはオブジェクトなので分割代入を使用して、関数のパラメータ内でPropsの値を明示的に指定することができます。

index.html
function Header({ title }) {
  console.log(title);
  return <h1>title</h1>;
}

ブラウザで確認確認するとTitleという文字が表示されているのがわかります。カスタムプロパティで<Header title="React" />と指定したはずなのになぜでしょう。

理由はreturn <h1>title</h1>で書いているtitleがプレーンテキストであるためです。この「titleはJavaScript変数です」ということをReactに伝えなければいけません。

JSXで変数を使用する

titlePropを以下の様にコードを変更しましょう。この書き方はJSXの特別な書き方で、{}で囲んだ内側では通常のJavaScriptが記載できます。

index.html
function Header({ title }) {
  console.log(title);
  return <h1>{title}</h1>;
}

他にも以下のような書き方でも表現可能です。

ピリオドを使用したオブジェクトのプロパティ参照(解説
example.js
function Header(props) {
  return <h1>{props.title}</h1>;
}
テンプレートリテラル(解説
example.js
function Header({ title }) {
  return <h1>{`Cool ${title}`}</h1>;
}
関数の戻り値(解説
eample.js
function createTitle(title) {
  if (title) {
    return title;
  } else {
    return 'Default title';
  }
}
 
function Header({ title }) {
  return <h1>{createTitle(title)}</h1>;
}
三項演算子(解説
example.js
function Header({ title }) {
  return <h1>{title ? title : 'Default title'}</h1>;
}
 
function HomePage() {
  return (
    <div>
      <Header />
    </div>
  );
}

リストの反復処理

リストとしてデータを表示したいケースはよくあります。同じスタイルで異なる情報を保持するUIの要素を作成するには、配列メソッドを使用してデータを操作しましょう。array.map()を使用することで、配列に対して繰り返し処理を実行し、異なるデータの要素を複数生成することができます。
array.map()についてはこちら

index.html
function HomePage() {
  const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
 
  return (
    <div>
      <Header title="Develop. Preview. Ship." />
      <ul>
        {names.map((name) => (
          <li>{name}</li>
        ))}
      </ul>
    </div>
  );
}

上記のコードを実行するとReactから「リスト内の各子要素は、一意な「key」Propを持つ必要があります」という警告が出ています。Reactがどの要素を更新すべきか判断するために、表示データだけではなく属性を持つ必要があるからです。

以下の様に表示データをそのままkeyとして宣言しましょう。

index.html
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>
    </div>
  );
}

State(状態)

React を使う場合、「ボタンを無効」、「ボタンを有効」、「成功メッセージを表示」といったコマンドを書くなど、コードから直接 UI を変更することはありません。コンポーネントのさまざまな視覚状態(「初期状態」、「入力中状態」、「成功状態」)に対して表示したい UI を先に記述し、ユーザ入力に応じて state の変更をトリガーします。

まずはstateevent handlersを使用して、どのようにインタラクティビティを追加するかを確認しましょう。
以下のコードではHomePageコンポーネントの中に「いいね!」ボタンであるbutton要素を作成しています。

index.html
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>
      <button>Like</button>
    </div>
  );
}

イベントのリッスン

ボタンがクリックされた際に何か実行するためにはonClickイベントを使用します。

index.html
function HomePage() {
  // ...
  return (
    <div>
      {/* ... */}
      <button onClick={}>Like</button>
    </div>
  );
}

イベントの処理

イベントがトリガーされるたびに「処理」する関数を定義することができます。
今回は return文の前にhandleClick()という関数を作成しトリガーされるたびに呼び出されるように設定しましょう。

index.html
function HomePage() {
  // 	...
  function handleClick() {
    console.log('increment like count');
  }
 
  return (
    <div>
      {/* ... */}
      <button onClick={handleClick}>Like</button>
    </div>
  );
}

ブラウザで実行して開発者ツールを起動し、ボタンを押すとログが出力されることを確認できます。

Stateとhooks

Reactには、Hookと呼ばれる一連の関数があります。 Hookを使えば、Stateのような追加ロジックをコンポーネントに追加できます。Stateとは、UIの中で時間の経過とともに変化する情報のことで、基本的にユーザーとのインタラクションによって変化します。

例えばStateを使用して、ユーザーが「いいね!」ボタンをクリックした回数を保存し、値をインクリメントすることができます。 Stateを管理するためのReact Hookの名前はuseState()です。では早速useState()をプロジェクトに追加しましょう。 useState()は配列を返すので、以下の様に配列の分割代入を使って、コンポーネント内部で配列の値にアクセスしたり使用したりすることができます

index.html
function HomePage() {
  // ...
  const [likes, setLikes] = React.useState(0);
 
  function handleClick() {
    setLikes(likes + 1);
  }
 
  return (
    <div>
      {/* ... */}
      <button onClick={handleClick}>Likes ({likes})</button>
    </div>
  );
}

まずはconst [likes, setLikes] = React.useState(0);をで指定している配列の第一項目には状態の名称を付けることができます。ここでは「いいね!」の数ということでlikesと名付けています。
配列の第二項目は値を更新する関数を指定する必要があります。宣言する関数名は自由に指定できますが、setLikesの様にset+変数名を付けるのが一般的です。
React.useState(0)(0)ではStateの初期値を設定することができます。今回はボタンが押されるまでは0を設定しています。
setLikes(likes + 1)では値更新後の値を渡しています。
{likes}を使用することで、更新された値を表示することができます。

ブラウザでボタンをクリックすると「いいね!」の数が増えていくことが確認できます。

Reactのまとめ

ここまでWeb開発の基本からReactの3つの概念であるComponent・Props・Stateとは何かということを実際にコードを書きながら解説してきました。DOMの操作が省略されて楽に開発が進められることを体験できたかと思います。
しかし、拡張性の高いアプリケーションを構築するには、まだまだ作業が必要です。サーバーのコンポーネントやクライアントのコンポーネントのようなフレームワークを必要尾する新しいReact機能もあります。
Next.jsはセットアップや設定の大部分を処理し、Reactアプリケーションの構築を手助けする追加機能を持っています。Reactのチュートリアルでも軽く触れているので、ここでも紹介します。

Next.jsへの移行

Next.jsのインストール

Next.jsを使用する場合reactスクリプトやreact-domスクリプトをunpkg.comから読み込む必要はありません。npmなどのパッケージマネージャーからインストールすることでNext.jsを使用することができます。

今回はnpmを使用してインストールするので{}と書かれたpackage.jsonを作成します。

続いて、ターミナルからnpm install react@latest react-dom@latest next@latestを入力して各ライブラリをインストールします。
コマンドを入力するとpackage.jsonに以下のような依存関係が追加され、package-lock.jsonが生成されます。

pacage.json
{
  "dependencies": {
    "next": "^14.0.3",
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  }
}

HTMLファイルからJSファイルへの変更

HTMLで定義していたその他のタグはNext.jsが肩代わりしてくれています。
ファイル名をindex.htmlからindex.jsに変更し、以下のコードに変更してみましょう。

index.js
import { useState } from 'react';
 
function Header({ title }) {
  return <h1>{title ? title : 'Default title'}</h1>;
}
 
function HomePage() {
  const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
 
  const [likes, setLikes] = useState(0);
 
  function handleClick() {
    setLikes(likes + 1);
  }
 
  return (
    <div>
      <Header title="Develop. Preview. Ship." />
      <ul>
        {names.map((name) => (
          <li key={name}>{name}</li>
        ))}
      </ul>
 
      <button onClick={handleClick}>Like ({likes})</button>
    </div>
  );
}

トップページの作成

Next.jsはファイルシステムのルーティングを使用しているため、コードを使用してアプリケーションのルートを定義しています。以下の手順でトップページを作成しましょう。

  1. appフォルダを作成し、index.jsを中に入れましょう
  2. index.jsファイルの名前をpage.jsに変更しましょう
    このファイルがアプリケーションのメインページになります
  3. export default<HomePage>コンポーネントに追加しましょう。
    Next.jsにメインコンポーネントでレンダリングするかを区別できるようにします。
page.js
import { useState } from 'react';
 
function Header({ title }) {
  return <h1>{title ? title : 'Default title'}</h1>;
}
 
export default function HomePage() {
  // ...
}

開発サーバーの実行

開発サーバーを実行して開発中の変更を確認できるようにしましょう。
package.jsonファイルに"next dev"スクリプトを追加しましょう。

package.json
{
  "scripts": {
    "dev": "next dev"
  },
  "dependencies": {
    "next": "^14.0.3",
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  }
}

ターミナルでnpm run devを実行して先ほど追加したスクリプトを実行してみましょう。

layout.jsというファイルが自動的にappフォルダ内に作成されました。これがアプリケーションのメインレイアウトになります。すべてのページで共有されるUI要素を追加するために使用できます。

また、先ほどの開発サーバーが起動されているので、ブラウザでhttp://localhost:3000/に接続して先ほどの変更を確認してみましょう。

コンパイルに失敗したというビルドエラーが出ていますね。

これはNext.jsがRSCと呼ばれるReactをサーバーでレンダリングできるようにする新機能を使用しているからです。しかしサーバーコンポーネントはuseStateをサポートしていないため、クライアントコンポーネントを使用する必要があります。

サーバーコンポーネントとクライアントコンポーネント

クライアントとサーバーという概念を理解する必要があります。Webアプリケーションでは以下の内容になります。

名称説明
クライアントユーザーのデバイス上のブラウザのこと。アプリケーションのコードに対するリクエストをサーバーに送信する。
サーバーデータセンターにあるPCのこと。アプリケーションのコードを保存し、クライアントからのリクエストを受け取り、計算を行い、適切なレスポンスを返す。

それぞれ独自の機能と制約があります。例えばレンダリングとデータ取得をサーバーに移すことで、クライアントに送信するデータ量を減らし、パフォーマンスを向上させることができます。ですが、UIをインタラクティブにするにはクライアントでDOMを更新しなければなりません。そのため、サーバーとクライアントでコードが異なるという場合があります。

ネットワークバウンダリー

ネットワークバウンダリーとは異なる環境を分ける概念的な線の名称です。Reactではコンポーネントツリーのどこにネットワークバウンダリーを配置するかを選択できます

この例ではサーバー上でデータを取得してユーザーの投稿をレンダリングし、クライアント上で投稿のインタラクティブな「いいね!」ボタンをレンダリングすることができます。同様にサーバー上でレンダリングされ、ページ間で共有されるNavコンポーネントを作成することができますが、リンクのアクティブな状態を表示したい場合はクライアント上でリンクのリストをレンダリングすることができます。

裏ではコンポーネントは2つのモジュールグラフに分割される。サーバーモジュールグラフにはサーバー上でレンダリングされるすべてのサーバーコンポーネントが、クライアントモジュールグラフにはクライアントコンポーネントが含まれます。サーバーコンポーネントがレンダリングされると、RSCペイロードと呼ばれる特殊なデータ形式がクライアントに送信されます。RSCペイロードには、サーバーコンポーネントのレンダリング結果と、クライアントコンポーネントがレンダリングされるPlaceholderや対象のJavaScript ファイルへの参照が含まれます。

Reactはこれらの情報を使用してサーバーとクライアントのコンポーネントを統合しDOMを更新しているのです。

クライアントコンポーネントへの移動

Next.jsはデフォルトでサーバーコンポーネントを使用します。アプリケーションのパフォーマンスを向上させるために追加の手順を踏む必要がないためです。

先ほどのエラーを確認すると、サーバーコンポーネント内でuseStateを使用していることを警告していました。「いいね!」ボタンはインタラクティブなボタンであるため、クライアントコンポーネントに移動することで修正することができます。

まずはappフォルダ内に「いいね!」ボタンコンポーネントをエクスポートするlike-button.jsを作成しましょう。<button>要素とhandleClick()関数そしてlikes状態をpage.jsからLikeButtonコンポーネントに移動します。

/app/like-button.js
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>;
}

そしてuse clientディレクティブをファイルの先頭に追加しましょう。
これを追加することでこのコンポーネントはクライアントでレンダリングするようにReactに指示することができます。

/app/like-button.js
'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コンポーネントをページにインポートします。

/app/page.js
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>
  );
}

変更が完了したら、ブラウザでhttp://localhost:3000/に接続してエラーが解消されたことを確認しましょう。

すでに開いている場合は変更を保存した際にページが自動で更新されたことに気が付いたと思います。これはNext.jsにあらかじめ設定されているFast Refreshと呼ばれる機能です。

まとめ

いかがでしょうか。初めはHTMLとJavaScript を使用してDOMを直接操作していました。Reactに移行してコードが減り書きやすくなったことを体験できたと思います。さらに最後ではNext.jsについても軽く触れました。Next.jsはRSCを使用してパフォーマンスを向上させるメジャーなフレームワークです。Reactについて学習した後はNext.jsについても学習することをお勧めいたします。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です