よく使い方を忘れるので、必要な時にサッと読み返せるように超完結にまとめておきます。
勉強中の関連記事まとめ
自分用の勉強記事をまとめた目次 ~擬似知識体系~
Next.jsとは
Reactでサーバーサイドレンダリングを可能とするJavascriptフレームワーク
Vue.jsでサーバーサイドレンダリングを可能とするNuxt.jsの親戚
- デフォルトでサーバーサイドレンダリング
- 高速ページローディングのため自動でコードスプリッティング
- シンプルなクライアントサイドでページごとにルーティングが作られる
- HMRをサポートしたWebpackベースの開発環境
- Expressや、どのNode.jsのHTTPサーバでも実行可能
- BabelやWebpackでの独自カスタマイズが容易
環境構築
公式サイトのチュートリアルに従って環境構築していく
セットアップ
mkdir test
cd test
npm init -y
npm install --save next react react-dom
mkdir pages
package.json
をエディタで開いく
vi package.json
npmスクリプト"scripts"
の値を,
の有無に注意しながら編集(ここの内容についてまだイマイチ理解してない)
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
devサーバーを起動する。
npm run dev
この段階ではhttp://localhost:3000/に接続しても、Next.jsのデフォルトの404ページが表示される
エラーページをカスタマイズするなら
pages/_error.js
を作成
Custom error handling
indexページを作成
トップページのindex.js
を作成
Next.js の Link API ではpages/
ディレクトリ配下のファイルのツリー構造にそって自動でルーティング(indexからの関係性)設定がされる
mkdir pages
vi pages/index.js
ページ内容を記述
pages/
ディレクトリ配下のファイルでReactコンポーネントをdefault exportさせることで、ページのコンポーネントとして認識
const Index = () => (
<div>
<p>ようこそ</p>
</div>
);
export default Index;
↓なんだこれ?
export default () => <div>ようこそ</div>
devサーバーを起動
npm run dev
http://localhost:3000/aboutに接続して動作確認
indexページとaboutページをそれぞれ作成したがまだ相互にリンクされていない
aboutページを作成
トップページ意外に固定ページとしてpages/
にaboutページを作成
vi pages/about.js
ページの内容を記述
export default function About() {
return (
<div>
<p>このサイトについて</p>
</div>
);
}
http://localhost:3000/aboutに接続するとaboutページが表示される
しかし、indexとaboutをそれぞれ作成したが、まだ相互にリンクされていない
固定ページへのリンク
indexとaboutの2つのページをリンクさせるためにnext/link
を使用する
Next.jsのLink APIを使用
Linkページをプリフェッチしているため、この遷移はページを更新せずにすなわちクライアントサイドで処理され、サーバーサイドにはリクエストされずにナビゲーションされる
ブラウザの戻るボタンを押すと、クライアントサイドのみで戻ります。これはつまり、next/linkがlocation.historyをすべてハンドリングしてくれているわけです。
pages/index.js
にコードを追記
// This is the Link API
import Link from 'next/link';
const Index = () => (
<div>
<Link href="/about">
<a>このページについて</a>
</Link>
<p>ようこそ</p>
</div>
);
export default Index;
抜粋すると、<link>
タグでレンダリングした要素にnext/link
をインポートしている
<a href="/about">このページについて</a>
// これをnext/Linkで使うと下のようになる
<Link href="/about">
<a>このページについて</a>
</Link>
http://localhost:3000/にアクセスするとaboutページへのリンクが表示される
<Link>
タグにtitle属性を追加
<Link href="/about" title="About Page">
<a>About Page</a>
</Link>
中略
#レイアウトコンポーネント
複数ページで共通するレイアウトを記述するcomponents/MyLayout.js
を作成
ここでHeaderやFooterのレイアウトを設定する
import Header from './Header'
const layoutStyle = {
margin: 20,
padding: 20,
border: '1px solid #DDD'
}
const Layout = (props) => (
<div style={layoutStyle}>
<Header />
{props.children}
</div>
)
export default Layout
MyLayout.js
を各ページでインポート
import Layout from '../components/MyLayout.js'
export default () => (
<Layout>
<p>Hello Next.js</p>
</Layout>
)
import Layout from '../components/MyLayout.js'
export default () => (
<Layout>
<p>This is the about page</p>
</Layout>
)
#制作中サイトのコード
自分のサイトをNext.js仕様にしている最中のコード。
import Link from 'next/link'; // next.jsのlink APIを読み込み
const linkStyle = { // <Link>タグのcss
marginRight: 15
};
const Header = () => ( // Headerテンプレートの中身を定数Headerに代入
<div>
<Link href="/"> // トップページへのリンク
<a style={linkStyle}>Home</a>
</Link>
<Link href="/profile"> // プロフィールページへのリンク
<a style={linkStyle}>Profile</a>
</Link>
</div>
);
export default Header; // Headerという名前で呼び出せるように書き出す
import Header from '../components/Header'; // Headerテンプレートを読み込み
const layoutStyle = { // レイアウトのcssを定数layoutStyleに代入
margin: 20,
padding: 20,
border: '1px solid #DDD'
};
const Layout = props => (
<div style={layoutStyle}> // <div>のcssとしてlayoutStyleを適用
<Header /> // Headerテンプレートを適用
{props.children} // pages/の固定ページの要素を読み込み
</div>
);
export default Layout; // Layoutという名前で呼び出せるように書き出す
import Layout from '../components/MyLayouts'; // MyLayoutテンプレートを読み込み
export default function Index() {
return (
<Layout> // Layoutテンプレートを適用
<p>サイト名</p> /// {props.children}で読み込む内容を記述
</Layout>
);
}
import Layout from '../components/MyLayouts';
export default function Profile() {
return (
<Layout>
<p>Profile</p>
</Layout>
);
}
###レイアウトコンポーネントの使い方は2種類
1つ目は、公式チュートリアルにある「Method 1 - Layout as a Higher Order Component(高次コンポーネントとしてのレイアウト)」について。MyLayout.js
をインポートしてレイアウト情報の入った定数withLayout
を取得しておき、固定ページのコンテンツが入った定数Page
の値を、export default
の関数withLayout
の引数として渡して<Page />
の位置に吐き出すという処理。
2つ目は、公式チュートリアルにある「Method 2 - Page content as a prop(小道具としてのページコンテンツ)」について。MyLayout.js
をインポートしてレイアウト情報の入った定数Layout
を取得しておき、固定ページの<Layout>
の中身の要素の入った定数IndexPageContent
の値を、export default
の関数で{props.children}
の位置に吐き出すという処理。
どっちが使いやすいか、どういう使い分けをするのかは、分からん。
参考文献
Using Shared Components(共有コンポーネントの使用) - Next.js公式チュートリアル