ページとレイアウト
Pages Router は、ページという概念に基づいたファイルシステムベースのルーターを備えています。
pages ディレクトリにファイルを追加すると、自動的にルートとして利用可能になります。
Next.js では、ページとは、pages ディレクトリ内の .js、.jsx、.ts、または .tsx ファイルからエクスポートされた React コンポーネント です。各ページは、ファイル名に基づいてルートに関連付けられます。
例: 以下のような React コンポーネントをエクスポートする pages/about.js を作成した場合、/about でアクセスできるようになります。
export default function About() {
return <div>About</div>
}インデックスルート
ルーターは、index という名前のファイルをディレクトリのルートに自動的にルーティングします。
pages/index.js→/pages/blog/index.js→/blog
ネストされたルート
ルーターはネストされたファイルをサポートしています。ネストされたフォルダー構造を作成すると、ファイルは引き続き自動的に同じようにルーティングされます。
pages/blog/first-post.js→/blog/first-postpages/dashboard/settings/username.js→/dashboard/settings/username
動的ルートを持つページ
Next.js は動的ルートを持つページをサポートしています。たとえば、pages/posts/[id].js という名前のファイルを作成すると、posts/1、posts/2 などにアクセスできるようになります。
動的ルーティングの詳細については、動的ルーティングのドキュメントを参照してください。
レイアウトパターン
React モデルでは、ページをコンポーネントのシリーズに分解できます。これらのコンポーネントの多くは、ページ間で再利用されることがよくあります。たとえば、すべてのページに同じナビゲーションバーとフッターがある場合があります。
import Navbar from './navbar'
import Footer from './footer'
export default function Layout({ children }) {
return (
<>
<Navbar />
<main>{children}</main>
<Footer />
</>
)
}例
カスタムアプリによる単一共有レイアウト
アプリケーション全体でレイアウトが 1 つしかない場合は、カスタムアプリを作成し、レイアウトでアプリケーションをラップできます。<Layout /> コンポーネントはページが変更されるたびに再利用されるため、コンポーネントの状態 (入力値など) は保持されます。
import Layout from '../components/layout'
export default function MyApp({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}ページごとのレイアウト
複数のレイアウトが必要な場合は、ページに getLayout プロパティを追加することで、レイアウトの React コンポーネントを返すことができます。これにより、ページごとにレイアウトを定義できます。関数を返しているため、必要に応じて複雑なネストされたレイアウトを作成できます。
import Layout from '../components/layout'
import NestedLayout from '../components/nested-layout'
export default function Page() {
return (
/** Your content */
)
}
Page.getLayout = function getLayout(page) {
return (
<Layout>
<NestedLayout>{page}</NestedLayout>
</Layout>
)
}export default function MyApp({ Component, pageProps }) {
// Use the layout defined at the page level, if available
const getLayout = Component.getLayout ?? ((page) => page)
return getLayout(<Component {...pageProps} />)
}ページ間を移動する際に、シングルページアプリケーション (SPA) 体験のために、ページの状態 (入力値、スクロール位置など) を保持したいと考えています。
このレイアウトパターンは、ページ遷移間で React コンポーネントツリーが維持されるため、状態の永続化を可能にします。コンポーネントツリーがあれば、React はどの要素が変更されたかを理解して状態を保持できます。
知っておくと良いこと: このプロセスはリコンシリエーションと呼ばれ、React がどの要素が変更されたかを理解する方法です。
TypeScript を使用する場合
TypeScript を使用する場合、まず getLayout 関数を含む新しい型をページ用に作成する必要があります。次に、以前に作成した型を使用するように Component プロパティをオーバーライドする新しい型を AppProps 用に作成する必要があります。
import type { ReactElement } from 'react'
import Layout from '../components/layout'
import NestedLayout from '../components/nested-layout'
import type { NextPageWithLayout } from './_app'
const Page: NextPageWithLayout = () => {
return <p>hello world</p>
}
Page.getLayout = function getLayout(page: ReactElement) {
return (
<Layout>
<NestedLayout>{page}</NestedLayout>
</Layout>
)
}
export default Pageimport type { ReactElement, ReactNode } from 'react'
import type { NextPage } from 'next'
import type { AppProps } from 'next/app'
export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
getLayout?: (page: ReactElement) => ReactNode
}
type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout
}
export default function MyApp({ Component, pageProps }: AppPropsWithLayout) {
// Use the layout defined at the page level, if available
const getLayout = Component.getLayout ?? ((page) => page)
return getLayout(<Component {...pageProps} />)
}Data Fetching
レイアウト内では、useEffect または SWR のようなライブラリを使用して、クライアントサイドでデータを取得できます。このファイルは ページではないため、現時点では getStaticProps または getServerSideProps を使用できません。
import useSWR from 'swr'
import Navbar from './navbar'
import Footer from './footer'
export default function Layout({ children }) {
const { data, error } = useSWR('/api/navigation', fetcher)
if (error) return <div>Failed to load</div>
if (!data) return <div>Loading...</div>
return (
<>
<Navbar links={data.links} />
<main>{children}</main>
<Footer />
</>
)
}役に立ちましたか?