🦕

【Next.js】レイアウトのコンポーネントをPageに直接書くパターン とgetLayoutを使うパターンの比較

2022/09/11に公開

Next.jsにおけるレイアウトの使用方法や概要については、以下の記事が非常に参考になります。
感謝します。
この記事では、もっと感覚的に理解できることを目的に書きました。

https://nextjs.org/docs/basic-features/layouts
https://zenn.dev/hisho/articles/fe9f4ec4a8e691
https://zenn.dev/a_da_chi/articles/7334e855cdfabb

今回使用するレイアウトは以下のものを使います。

import React, { useState } from "react";

export const LayoutA = ({ children }) => {
  const [count, setCount] = useState(0);

  return (
    <>
      <div>LayoutA</div>
      <button onClick={() => setCount(++count)}>LayoutA Button</button>
      <div>{`カウント総数${count}`}</div>
      <div>{children}</div>
    </>
  );
};

レイアウトのコンポーネントを直接書くパターン

usingLayoutAとusingLayoutA2で使用します。

usingLayoutA.js
import Link from "next/link";
import React from "react";
import { LayoutA } from "../components/layout/LayoutA";

export default function usingLayoutA() {
  return (
    <>
      <LayoutA>
        <div>ここはusingLayoutAのページです</div>
        <div>
          <Link href="/usingLayoutA2">
            <a>usingLayoutA2ページに移動する</a>
          </Link>
        </div>
      </LayoutA>
    </>
  );
}
usingLayoutA2.js
import Link from "next/link";
import React from "react";
import { LayoutA } from "../components/layout/LayoutA";

export default function usingLayoutA2() {
  return (
    <LayoutA>
      <div>ここはusingLayoutA2ページです</div>
      <div>
        <Link href="/usingLayoutA">
          <a>usingLayoutAページに移動する</a>
        </Link>
      </div>
    </LayoutA>
  );
}


ページusingLayoutA2ページに移動すると、ステイトとして持たせたカウントが初期化されています。

ステイトとページ遷移がらみでの補足ですが、

Next.js で同じページに移動する場合、親コンポーネントが変更されない限り、react はアンマウントしないため、ページの状態はデフォルトではリセットされません。

https://nextjs.org/docs/api-reference/next/router

getLayoutを使うパターン

_app.js
import "../styles/globals.css";

function MyApp({ Component, pageProps }) {
  const getLayout = Component.getLayout ?? ((page) => page);

  return getLayout(<Component {...pageProps} />);
}

export default MyApp;

usingLayoutA.js
import Link from "next/link";
import React from "react";
import { LayoutA } from "../components/layout/LayoutA";

export default function usingLayoutA() {
  return (
    <>
      <div>ここはusingLayoutAのページです</div>
      <div>
        <Link href="/usingLayoutA2">
          <a>usingLayoutA2ページに移動する</a>
        </Link>
      </div>
    </>
  );
}

usingLayoutA.getLayout = function getLayout(page) {
  return <LayoutA>{page}</LayoutA>;
};
usingLayoutA2.js
import Link from "next/link";
import React from "react";
import { LayoutA } from "../components/layout/LayoutA";

export default function usingLayoutA2() {
  return (
    <>
      <div>ここはusingLayoutA2ページです</div>
      <div>
        <Link href="/usingLayoutA">
          <a>usingLayoutAページに移動する</a>
        </Link>
      </div>
    </>
  );
}

usingLayoutA2.getLayout = function getLayout(page) {
  return <LayoutA>{page}</LayoutA>;
};


ページusingLayoutAでカウントをした後に、ページusingLayoutA2に遷移しても、カウントが維持されていることが分かる。

Discussion