はじめに
BB.excite事業部でエンジニアをしている小川です。
はじめに注意書きですが、本記事ではNext.js 12.x の Layouts機能を取り扱います。
Next.jsのPages Routerには同じ要素を再利用するための機能としてLayoutパターンが用意されています。 また、Layoutはページ遷移時に再レンダリングが行われないようになっているため、状態を維持できるようになっていることが特徴的です。
全てのページに共通して同一のレイアウトということであれば_app.jsなどにLayoutを適用すれば済む話ですが、大抵はページごとに多少の違いを持たせたくなるものです。
今回はレイアウトを変えるほどではないけれど、propsで多少の変更を加えたい!というときにpropsを渡す方法があるのでご紹介です。
Per-Page Layoutsを使ってみる
まずは公式ドキュメントで紹介されているベーシックなLayoutを定義します。
components/BasicLayout.jsx
import Navbar from './navbar' import Footer from './footer' export const BasicLayout = (page) => { return ( <> <Navbar /> <main>{page}</main> <Footer /> </> ) }
定義したレイアウトを使うときは以下のような記述になります。
pages/index.jsx
import BasicLayout from '../components/basic-layout' export default const Page = () => { return ( /** Your content */ ) } Page.getLayout = (page) => BasicLayout(page) // ← ココ
レイアウトの定義をいくつかしておいて、呼び出し側でどのレイアウトを呼び出すか決めれば使い分けられて便利ですね。
propsを渡す
ここからが本題で、Layoutでpropsを受け取れるようにします。
components/basic-layout.jsx
import Navbar from './navbar' import Footer from './footer' export const BasicLayout = (page, props) => { return ( <> <Navbar /> <p>{props}</p> <main>{page}</main> <Footer /> </> ) }
Layoutを呼び出す側では以下のように記述して渡します。 単純に第2引数で渡すだけですね。
pages/index.jsx
import BasicLayout from '../components/basic-layout' export default const Page = () => { return ( /** Your content */ ) } const props = "sample text" Page.getLayout = (page) => BasicLayout(page, props) // ← ココ
最近のドキュメントやNext.jsのexampleを見ていると以下のような記述もできるようです。
この辺りはお好みでしょうか。
pages/index.jsx
import BasicLayout from '../components/basic-layout' export default const Page = () => { return ( /** Your content */ ) } Page.getLayout = (page) => { <BasicLayout> <p>propsを渡さなくてもちょっとした内容であればここに書ける</p> {page} </BasicLayout> }