Next.jsの基本まとめ

準備

npm init next-app <APPNAME>
npm run dev

ページの編集

/pagesの各jsxファイルがそのままページになる。
・ファイル名=パスネーム
index/

コンポーネントをexport defaultすればいい。

// 例
export default function () {
    return <h1>First Post</h1>
}
// このようにコンポーネント定義を省略できる。普通に関数またはクラスで定義してもいい。

ページ遷移(Linkタグ)

普通にaタグも使えるが、Linkタグで擬似ページ遷移できる

import Link from 'next/link'

<Link href="/">
    <>
         <a href="/">Back</a> to home
    </>
</Link>
// 空タグを使えば、不要な囲いタグを回避できる
// Link内はどこをクリックしてもLink.hrefに擬似遷移する。上の例のように、SEO目的などでaタグを設定することもできる。その場合でも、そのaタグではなくLinkのクリックが優先される。

Linkではなくaタグを使った場合は擬似遷移でなく普通に遷移する。

スタティック(静的)ファイル

プロジェクトディレクトリ/public/に置いたファイルは/ファイル名でホストされる。
メタデータとかどう設定すればいいのかな?は多分ここに書いてある
Basic Features: Static File Serving | Next.js

headタグ内へのアクセス

Headコンポーネントをレンダーすればいい。

// 例
import Head from 'next/head';

export default function () {
  return (
    <>
      <Head>
        <title>Create Next App</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <div>
        ...
      </div>
    </>
  )
}

CSSとコンポーネント

コンポーネントとCSSモジュールの準備

コンポーネント:プロジェクトディレクトリ/components/以下に任意の.jsファイルを置く。
CSSモジュール:プロジェクトディレクトリ/components/以下に任意の.modules.cssファイルを置く。

// xxx.modules.cssのファイルを用意すればCSSモジュールを利用できる
import styles from './layout.module.css';

export default function Layout({ children, arg1, arg2, ... }) {
	return <div className={styles.container}>{children}</div>
}
// children(引数)には、layoutコンポーネントの子要素がそのまま入る
// arg1, arg2...にはコンポーネント呼び出し時に任意の変数を代入できる 
// styles.クラス名 で、xxx.modules.cssの各クラスにアクセス

exportしたコンポーネントを他のコンポーネントやページで利用できる。

// ページ
import Layout from '../components/layout';

export default function () {
    return <Layout arg1>...</Layout>
}

CSSモジュールの挙動

// xxx.modules.cssのファイルを用意すればCSSモジュールを利用できる
import styles from './layout.module.css';

export default function Layout({ children }) {
	return <div className={styles.container}>{children}</div>
}
// children(引数)には、layoutコンポーネントの子要素がそのまま入る
// styles.クラス名 で、xxx.modules.cssの各クラスにアクセス

グローバルスタイリング(トップレベルコンポーネントとグローバルCSS)

トップレベルコンポーネント(グローバルApp)

プロジェクトディレクトリ/pages/直下に_app.jsファイルを置く。

// _app.js

export default function App({ Component, pageProps }) {
  return <Component {...pageProps} />
}

これでトップレベルコンポーネントAppを定義できた。
開発サーバを起動している場合は、再起動が必要。

グローバルCSS

といっても、特別なことはない。トップレベルコンポーネントAppでimportしたCSSがグローバルCSSになる。
ただimportすればいい。

// _app.js

import '../styles/global.css'

export default function App({ Component, pageProps }) {
  return <Component {...pageProps} />
}

importするCSSのファイル名や配置場所に制限はない。

便利なモジュール

classnames

インストール
npm install classnames
価値と利用方法

CSSモジュールを利用するには、className={styles.クラス名}でなければいけない。変数によってクラス名を変えたい場合に、このままでは面倒。

// 例
import styles from './alert.module.css'
import classnames from 'classnames'

export default function Alert({ type }) {
  return (
    <div
      className={classnames({
        [styles.success]: type === 'success',
        [styles.error]: type === 'error'
      })}
    >
      {children}
    </div>
  )
}

{[styles.クラス名]:真偽判定}で真のクラス名がリストに追加される(んだと思う)。

PostCSS (デフォルトのCSSコンパイラ)のカスタマイズ

postcss.config.jsというファイルをトップレベルに作成して PostCSS の設定をカスタマイズできる。

// Tailwind CSS を purgecss と合わせて使うときの例
// tailwindcss、@fullhuman/postcss-purgecss、および postcss-preset-env をインストールする必要がある
// autoprefixer はデフォルトで Next.js に含まれているため不要

module.exports = {
  plugins: [
    'tailwindcss',
    ...(process.env.NODE_ENV === 'production'
      ? [
          [
            '@fullhuman/postcss-purgecss',
            {
              content: [
                './pages/**/*.{js,jsx,ts,tsx}',
                './components/**/*.{js,jsx,ts,tsx}'
              ],
              defaultExtractor: content =>
                content.match(/[\w-/:]+(?<!:)/g) || []
            }
          ]
        ]
      : []),
    'postcss-preset-env'
  ]
}

詳しい書き方
Advanced Features: Customizing PostCSS Config | Next.js

Sass

npm install sassで、Sassを利用できる。
利用方法はcss同様。.sass (.scss).module.sass (.module.scss)を設置するだけ。

レンダリングとフェッチ

レンダリング

Next.jsではページ単位で3種類のレンダリングを選択できる。

  • 静的生成
  • サーバーサイドレンダリング(SSR)
  • クライアントサイドレンダリング
静的生成

ビルド時に外部データをフェッチ→レンダーしておく。

サーバーサイドレンダリング(SSR)

リクエストごとにサーバーサイドで外部データをフェッチ→レンダーする。

クライアントサイドレンダリング

通常のReactとは異なり、ビルド時に完結する部分(=外部データが不要)はプリレンダリングされる。
外部データはクライアントサイドでフェッチ→レンダーされる。

フェッチ

ドキュメント
Basic Features: Data fetching | Next.js

getStaticProps

getStaticProps中のコードはサーバーサイドでのみ実行されるし、クライアントに渡されることはない。ここで外部API叩くなりDBアクセスも可。

export default function (props) { ... }

export async function getStaticProps() {
    // ファイルシステムや API、DB などから外部データを取得する
    const data = ...

    // `props` キーに対応する値がデフォルトコンポーネントに渡される
    return {
        props: ...
    }
}
getServerSideProps

SSR用のフェッチ。

export async function getServerSideProps(context) {
  // contextにはリクエストパラメータが入る。
  return {
    props: {
      // コンポーネントに渡すための props
    }
  }
}

Contextについて
Basic Features: Data fetching | Next.js

SWR

クライアントで外部データを取得する場合はSWRが推奨らしい。

// 使用例
import useSWR from 'swr'

function Profile() {
  const { data, error } = useSWR('/api/user', fetch)

  if (error) return <div>failed to load</div>
  if (!data) return <div>loading...</div>
  return <div>hello {data.name}!</div>
}

ドキュメント
SWR: React Hooks for Remote Data Fetching

動的ルーティング

ドキュメント
Routing: Dynamic Routes | Next.js

ファイルの準備とパス変数の受取

[xxx].jsというファイル名で保存したとき、params.xxxがパス変数(文字列)となる。
[...xxx].jsというファイル名で保存したときは、以降のパス文字列すべてを変数として受け取る。params.xxx/でスプリットしたパス変数リストになる。(例:a/b/cであればparams.xxx = ['a', 'b', 'c']

// [id].js

import Layout from '../../components/layout'

export default function Post() {
  return <Layout>...</Layout>
}

export async function getStaticPaths() {
  // id としてとりうる値のリストを返す
  // リストは、以下のようにparamsキーとxxxキーを含む必要がある。
  return [
    {
      params: {
        id: 'ssg-ssr'
      }
    },
    {
      params: {
        id: 'pre-rendering'
      }
    }
  ]
}

export async function getStaticProps({ params }) {
  // params.id を使用して、ブログの投稿に必要なデータを取得する
}

動的ルーティングページへのリンク

<Link href="/posts/[id]" as="/posts/ssg-ssr">
  <a>...</a>
</Link>

fallback

未定義のパスリクエストに対するレスポンスについて。fallback : falseであれば、404を返す。fallback : trueのときは「fallbackページ」を返す。

  return {
    paths,
    fallback: false
  }

ドキュメント
Basic Features: Data fetching | Next.js

エラーページ

404ページであればpages/404.jsを置くだけでいい。

ドキュメント
Advanced Features: Custom Error Page | Next.js

APIルート

以下のような形でページコンポーネントを出力すればいい。

export default (req, res) => {
  res.status(200).json({ text: 'Hello' })
}

reqreshttp.IncomingMessagehttp.ServerResponseのインスタンスで、加えてミドルウェア、ヘルパー関数ももつ。

詳しくはドキュメント。
HTTP | Node.js v14.1.0 Documentation
HTTP | Node.js v14.1.0 Documentation
API Routes: API Middlewares | Next.js
API Routes: Response Helpers | Next.js

APIルートのコードはクライアント側のバンドルには含まれない。

デプロイ

Next.js純正プラットフォームのVercelがある。

coming soon...