19
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の基礎

Last updated at Posted at 2019-10-14

next.jsのチュートリアルをやっているので、基礎的な項目を羅列します。

Next.js チュートリアルの基本項目

1. ページ間の移動
2. 共有コンポーネントの使用
3. 共通化
4. 動的ページの作成

1. ページ間の移動

  • next.jsでは、[プロジェクト名]/pages直下にhoge.jsなど各ページのjsファイルを作成することでページの追加ができる。

    • nextにおいて特別なディレクトリは、このpagesstaticディレクトリ
    • その他のディレクトリは自由に設定できる
  • ページ間の移動は、Linkコンポーネントを使う

    • 通常のアンカータグのみでのリンク移動ではだめ。
    • 目的のページは表示されるが、再読み込みされてしまうから。→SPAの意味がない
js(index.js)
~
<div>
  <a href="/about">About Page</a>
</div>
~

↑こうではなく、こう↓

import "Link" from 'next/Link';
~
<div>
  <Link href="/about">
    <a>About Page</a>
  </Link>
</div>
~

Linkコンポーネントのにhref属性として遷移先のパスを指定する。

2. 共有コンポーネントの使用

以下、indexページとaboutページの2ページがあるとする。
これらの中身を見ると、各ページへのリンクがあるヘッダー部分が共通である。

index.js
import Link from 'next/link';

export default function Index() {
  return (
    <div>
      // ここから共通部
      <Link href="/">
        <a>Home</a>
      </Link>
      <Link href="/about">
        <a>About</a>
      </Link>
      // ここまで共通部
      <p>This is index page.</p>
    </div>
  );
}
about.js
import Link from 'next/link';

export default function About() {
  return (
    <div>
      // ここから共通部
      <Link href="/">
        <a>Home</a>
      </Link>
      <Link href="/about">
        <a>About</a>
      </Link>
      // ここまで共通部
      <p>This is about page.</p>
    </div>
  );
}

3. 共通化

この共通部分を新たにコンポーネント化して、共有しよう。

ヘッダーコンポーネントを新規作成する。(/components/Header.js)

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

const Header = () => (
  <div>
    // ここから共通だった部分
    <Link href="/">
      <a style={linkStyle}>Home</a>
    </Link>
    <Link href="/about">
      <a style={linkStyle}>About</a>
    </Link>
    // ここまで共通だった部分
  </div>
);

export default Header;

もとのindexとaboutページは以下のように変更する。

index.js
import Header from '../components/Header.js';

export default function Index() {
  return(
    <div>
      <Header />    // ここが共通部
      <p>This is index page.</p>
    </div>
  );
}
about.js
import Header from '../components/Header.js';

export default function About() {
  return(
    <div>
      <Header />    // ここが共通部
      <p>This is about page.</p>
    </div>
  );
}

このように、コンポーネントの共通部分は新たに共通化することで、複数の同じコードを書かなくて済む。
今後共通部に変更があった場合の修正漏れの防止にもなる。

4. 動的ページの作成

以下のURLにアクセスすると、
http://localhost:3000/post?title=hello-world
クエリストリングのhello-worldが {router.query.title} に入る。

post.js
import { useRouter } from 'next/router';
import Layout from '../components/MyLayout';

const Page = () => {
  const router = useRouter();

  return (
    <Layout>
      <h1>{router.query.title}</h1>
      <p>content</p>
    </Layout>
  );
};

export default Page;

next/routeruseRouter はrouterオブジェクトを返す。
routerオブジェクトの query オブジェクトでクエリストリングを取得できる。

5. 動的ルーティング

4. 動的ページの生成では以下のURLで動的ページを作成した。
http://localhost:3000/post?title=hello-world

これをもっと綺麗なURLで実現したい。以下のような。
http://localhost:3000/p/hello-world

実現するにはまず、
pages/p/[id].js
を作成する。

[id].js
~
export default function Post() {
  const router = useRouter();

  return (
    <Layout>
      <h1>{router.query.id}</h1>
      <p>content</p>
    </Layout>
  );
}

ブラケット[]は動的ルーティングを可能にする。
/p/[id]のidにはクエリストリングが入る。
/p/hello-worldならrouter.queryは{id: 'hello-world'}になる。

上のポストページに飛ぶためのリンク元のindexページは以下のようになる。

index.js
~
const PostLink = props => (
  <li>
    <Link href="/p/[id]" as={`/p/${props.id}`}>
      <a>{props.id}</a>
    </Link>
  </li>
);

export default function Blog() {
  return (
    <Layout>
      <h1>My Blog</h1>
      <ul>
        <PostLink id="hello-world">
        <PostLink id="hello-next">
      </ul>
    </Layout>
  );
}

Linkのそれぞれの属性は以下のようになっている。

  • href:pagesフォルダのページパス + クエリストリング
  • as:ブラウザのURLバーに表示されるURL

19
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
19
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?