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> }
動的ルーティング
ドキュメント
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 }
APIルート
以下のような形でページコンポーネントを出力すればいい。
export default (req, res) => { res.status(200).json({ text: 'Hello' }) }
req
とres
はhttp.IncomingMessage
とhttp.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...