本日はNext.jsでのリンク(ルート)処理となります。
今回からのNext.js入門を始める方はまずはこちらからどうぞ
Next.jsはReactを使用しWebアプリケーションを構築する為の優れたツールの1つであり
最大の利点はルーティングを処理する事となります。
今までReactを学習されてきている方々であればルーティングライブラリと言えば『React-Router』での『Navi』リンクや最近では新しい『React Location』など色々扱ってきてるかと思います。
今回ではNext.jsアプリケーションでルーティングする際の静的と動的のルーティングの基礎を初学者様に説明していきますのでよろしくお願い致します。
リンクの前に軽くNext.jsでの関数定義はどうなのか気になる方もいらっしゃるかと思いますが
基本的にはReactの時とさほど変わりはありません。
Reactには、『function()』と『アロー関数(() ⇒ {})』の二つがあります。
functionキーワードとアロー関数の違い、様々な違いがあるのはJavaScriptを学習時に分かってらっしゃるかと思いますので飛ばしていきます。
export default function Home() { return( <div> <h1>Homeページです</h1> </div> ) }
const Home = () => { return( <div> <h1>Homeページです</h1> </div> ) } export default Home;
Reactの場合はファイル上部で『import React from ‘react’』のおまじないを記述しReactの宣言をしたりしますが『Next.js』では必要ありません。
それは『npm run dev』実行時にindex.jsファイルの更新とともに自動的に更新内容がブラウザに反映されるためです。
ですが現在、Reactではv17のバージョンアップによりNext.jsと同様にこの宣言import が不要になりました。
プロジェクトの準備をお願い致します。
npx create-next-app my-next-app cd my-next-app /開発者サーバーを立ち上げる npm run dev
もし不要なファイルが邪魔で削除しておきたい場合は
rm -r pages/api/ rm public/vercel.svg
カスタムLinkコンポーネント
まずは静的ルーティングから解説致します。
静的ルーティングでは『pages』という名前のフォルダがあり、アプリケーションのルーティングはこのフォルダとその中のファイルに完全に関連しています。
Next.jsもLinkコンポーネントがありますが他のインターフェースとは多少異なる部分があります。
ですがほとんどが同様に機能致します。
『< a >』タグの代わりに使用されるものとなります。
クリック時にページ全体のリダイレクトなしでURLが変更され、ルーティングが新しいページの読み込みと表示を処理してくれます。
ルーティングライブラリコンポーネントをラップします。
つまり『ReactRouter』の標準リンクコンポーネントのように機能させる、カスタムリンクコンポーネントという事になります。
まずは『pages/index.js』を開き、index.js内に記述してあるデフォルトのコードを全て削除して下さい。
下記のように記述をお願いします
const Home = () => { return( <div> <h1>Homeページです</h1> </div> ) } export default Home;
分かりやすくする為にCSSで軽くスタイリングします。
『styles/Home.module.css』内のデフォルトのコードもindex.js同様に全て削除して下さい。
.title { background-color: #0000FF; color: #fff; font-size: 2em; text-align: center; } /* ルーティング先のスタイル */ .about { background-color: #FF0000; color: #fff; font-size: 2em; text-align: center; }
cssは分かるかと思いますのでお好みでスタイリング下さい。
今回の記事では『layout』コンポーネントの実装は致しません。
index.js内で『Home.module.css』をインポートします。
import styles from '../styles/Home.module.css' <div> <h1 className={styles.title}>Homeページです</h1> </div>
私と同じようにスタイリングしているのであればこのようにブラウザで表示されてるかと思います。
Linkを使用できるようにインポートをします。
すべてのプロジェクトで、『Link』という名前の独自のコンポーネントを使用していきます。
import Link from 'next/link'
組み込みのNext.jsリンクコンポーネントはhref属性を受け入れますが、機能するには『< a >』タグをその中にネストする必要があります。
<Link href="/about/about"> <a>Aboutへ</a> </Link>
ルーティング先ページのファイル作成をしていきます。
『pages』直下に新たに『about』フォルダを作成します『pages/about』
aboutフォルダ内に『about.jsファイル』を作成していき
下記のように記述下さい。
import styles from '/styles/Home.module.css' import Link from 'next/link' const About = () => { return( <div> <h1 className={styles.about}>Aboutページです</h1> <Link href="/"><a>Back to Home</a></Link> </div> ) } export default About;
About.jsがルーティング先のページとなります。
保存して更新してからブラウザを確認下さい。
『Aboutへ』をクリックし『Back to Home』で行ったり来たりしてみて下さい。
DEMO
aタグではなくボタンタグにしたい場合は簡単です
aタグをbuttonタグに変更してあければ可能となります。
<Link href="/about/about"> <button>Aboutへ</button> </Link>
静的ルーティングはサーバー側のレンダリングに似ていますが、リクエストごとにHTMLを生成する代わりに、ビルド時にすべてを事前にコンパイルします。
企業のWebサイトなどの頻繁に変更がないサイトに非常に役立ちます。
動的ルートでの処理
Next.jsはアプリケーションをビルド時にすべてを事前にレンダリングされてユーザーに提供するページを備えたサイトであり『ユーザーが要求する前でもページを利用できます』
ですが静的レンダリングを使用すると、複雑なアプリケーションでは、事前定義されたパスを使用してルートを定義するだけでは必ずしも十分とは言えません。
それはすべての静的レンダリングはブラウザの外部で行われるためなので、唯一の問題点となります。
動的ルーティングでは、クエリパラメータを動的に渡しpagesフォルダを離れることなく動的ページを作成し、サーバー側のレンダリングを使用して動的なWebページ(ユーザーが新しい要求を行うたびに変更されるページ)を自動的に生成しています。
Next.jsのルーティングのアーキテクチャにより、ページの作成とリンクが非常に簡単となっています。
つまり動的ルートはURLからのクエリidに応じて、コンテンツを動的にレンダリングする特別なルートという事です。
『JSONデータ』に基づいてページは、特別なファイル名でページを作成し、2つの機能を実装することによって行われます。
その特別なファイル名には定義規則があります。
それはファイル名やフォルダ名を[]でラップしてあげる事となります。
pages/about/[about].js
この特別なファイルによって処理されていきます。
角かっこ[]を使用して動的なルートをネストすることも容易となります。
これを行うには『useRouter』フックをインポートして呼び出す必要があります。
『useRouter』はReactフックです。
import {useRouter} from 'next/router'
順番にいきましょう
まずは『about』フォルダ名を変更します。
[country]とします。
『about.js』は[city].jsに変更します。
pages/[country]/[city].js
index.jsファイルにそれぞれの国の都市の連想配列データを用意します。
先程のコードはそのままでお願いします。
const cityList = [ { country: "JPN", city: "Tokyo" }, { country: "USA", city: "NewYork" }, { country: "Spain", city: "Madrid" }, { country: "France", city: "Paris" } ];
[city].jsファイルに移動し下記のように記述下さい。
import styles from '/styles/Home.module.css'; import Link from 'next/link' import { useRouter } from 'next/router'; //呼び出し const About = () => { const router = useRouter(); const { country, city } = router.query; return( <div><h1 className={styles.about}>Aboutページです</h1> <Link href="/"><a>Back to Home</a></Link> <br /> { country }の都市は{city}です。 </div> ) } export default About;
インポートされた『useRouter』フックを使用し、ルート内のクエリパラメータの値にアクセスします。
『useRouter』は、現在のルートのオブジェクトをロケーションバーに返し、その変数に簡単にアクセスが容易となります。
index.jsファイルに戻りましょう
動的にルートが可能になるように書いていく必要があります。
const Home = () => { return( <div> <h1 className={styles.title}>Homeページです</h1> <Link href='/about/about'><button>Aboutへ</button></Link> //ここから {cityList.map((item, index) => ( <li key={index}> <Link as={`/${item.country}/${item.city}`} href="/[country]/[city]"><a> {item.country}<br /> {item.city} </a></Link> </li> ))} </div> ) }
『Link href=』の部分を見てもらうと『as』プロパティに変わってるかと思います。
これは正確なルートの際は『as』プロパティで渡す必要がある為です。
後はJavaScriptに精通がある方であれば説明は必要ないかと思います。
マップ関数とテンプレートリテラルでの実装です。
DEMO
動的ルートを拡張して、3つのドット(。。 。[ファイル名])で事前定義されたルートは、動的ルートよりも最優先され、これらはすべてのルートをキャッチします。
Next.jsアプリケーションで静的ルーティングと動的ルーティングを正常に実装する方法のご紹介でした。
本日は以上となります。
最後まで読んで頂きありがとうございました。
当ブログでの記事でNext.jsで正確なルート処理でルーティングする方法に役に立ってくれたら幸いでございます。