16
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Next.jsのインストールとルーティングの基礎

16
Last updated at Posted at 2019-04-09

Next.jsとは?

Next.jsとは、Reactのユニバーサルフレームワークです。Nowでお馴染みのzeit.coが開発していて、以下のような特徴があります。

  • SSR(サーバーサイドレンダリング)
  • 高速なページロードのための自動コード分割
  • ページベースのクライアントサイドルーティング
  • webpackベースの開発環境で、Hot Module Replacement(HMR)をサポート
  • Express等のHTTPサーバーと一緒に実装可能
  • Babelやwebpackの設定をカスタマイズ可能

このエントリーでは、公式のチュートリアルをもとに、Next.jsのインストールと、ルーティングの基礎をまとめてみました。

インストール

$ mkdir hello-next
$ cd hello-next
$ npm init -y
$ npm install --save react react-dom next
$ mkdir pages

package.jsonには以下のnpm scriptsを記述します。

{
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  }
}

npm run devhttp://localhost:3000にローカルサーバーが立ち上がります。現在は404になっているので、簡単なページを追加してみましょう。

// pages/index.js
const Index = () => (
  <div>
    <p>Hello Next.js</p>
  </div>
)

export default Index

ブラウザ上にHello Next.jsが表示されたかと思います。

ディレクトリの命名規則とルーティング

Next.jsでは、pagesディレクトリがルーティングの対象になります。それ以外のコンポーネントを配置するディレクトリ名にルールはなく、たとえばコンポーネント用のディレクトリは、componentsでも、compsでもなんでもOKです。

シンプルなルーティング

// pages/index.js

// This is the Link API
import Link from 'next/link'

const Index = () => (
  <div>
    <Link href="/about">
      <a>About Page</a>
    </Link>
    <p>Hello Next.js</p>
  </div>
)

export default Index
// pages/about.js
const About = () => {

  // ヒストリーバックでもOK
  const historyBack = () => {
    history.back()
  }
  
  return (
    <div>
      <button onClick={historyBack}>History Back</button>
      <p>This is About Page</p>
    </div>
  )
}

export default About

共通コンポーネントを使用

// components/Header.js
import Link from 'next/link'

// スタイル
const linkStyle = {
  marginRight: 15
}

// ヘッダー用コンポーネント
const Header = () => (
  <div>
    <Link href="/">
      <a style={linkStyle}>Home</a>
    </Link>
    <Link href="/about">
      <a style={linkStyle}>About</a>
    </Link>
  </div>
)

export default Header
// pages/index.js
import Header from '../components/Header'

const Index = () => (
  <div>
    <Header />
    <p>Hello Next.js</p>
  </div>
)

export default Index
// pages/about.js
import Header from '../components/Header'

const About = () => (
  <div>
    <Header />
    <p>This is About Page</p>
  </div>
)

export default About

Layoutを継承

ベースとなるレイアウトコンポーネントを作成し、継承できます。ページコンポーネントの受け取り方はいくつかありますので、チュートリアルで紹介されているほうほうをご紹介します。

childrenでページコンポーネントを受け取る

// components/MyLayout.js
import Header from './Header'

const layoutStyle = {
  margin: 20,
  padding: 20,
  border: '1px solid #DDD'
}

const Layout = props => (
  <div style={layoutStyle}>
    <Header />
    {
      // 引数でpages/*.jsのJSXを受け取る
      props.children
    }
  </div>
)

export default Layout
// components/Header.js
import Link from 'next/link'

// スタイル
const linkStyle = {
  marginRight: 15
}

// ヘッダー用コンポーネント
const Header = () => (
  <div>
    <Link href="/">
      <a style={linkStyle}>Home</a>
    </Link>
    <Link href="/about">
      <a style={linkStyle}>About</a>
    </Link>
  </div>
)

export default Header
// pages/index.js
import Layout from '../components/MyLayout'

const Index = () => (

  // カスタムエレメントの小要素が渡される
  <Layout>
    <p>Hello Next.js</p>
  </Layout>
)

export default Index
// pages/about.js
import Layout from '../components/MyLayout'

const About = () => (

  // カスタムエレメントの小要素が渡される
  <Layout>
    <p>This is About Page</p>
  </Layout>
)

export default About

ページコンポーネントをカスタムエレメントで受け取る

// components/MyLayout.js
import Header from './Header'

const layoutStyle = {
  margin: 20,
  padding: 20,
  border: '1px solid #DDD'
}

const withLayout = Page => {
  return () => (
    <div style={layoutStyle}>
      <Header />
      <Page />
    </div>
  )
}

export default withLayout
// pages/index.js
import withLayout from '../components/MyLayout'

const Page = () => <p>Hello Next.js</p>

export default withLayout(Page)

// pages/about.js
import withLayout from '../components/MyLayout'

const Page = () => <p>This is the about page</p>

export default withLayout(Page)

contentでページコンポーネントを受け取る

// components/MyLayout.js
import Header from './Header'

const layoutStyle = {
  margin: 20,
  padding: 20,
  border: '1px solid #DDD'
}

const Layout = props => (
  <div style={layoutStyle}>
    <Header />
    {
      // 引数でpages/*.jsのJSXを受け取る
      props.content
    }
  </div>
)

export default Layout

// pages/index.js
import Layout from '../components/MyLayout.js'

const indexPageContent = <p>Hello Next.js</p>

export default function Index() {

  // カスタムエレメントのpropsでJSXを渡す
  return <Layout content={indexPageContent} />
}

// pages/about.js
import Layout from '../components/MyLayout.js'

const aboutPageContent = <p>This is the about page</p>

export default function About() {

  // カスタムエレメントのpropsでJSXを渡す
  return <Layout content={aboutPageContent} />
}

ちなみに、チュートリアルのUsing Shared Componentsまでの内容です。

続きはまた。

16
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?