Next.jsの基礎

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

# Next.js チュートリアルの基本項目
[1. ページ間の移動](#1-ページ間の移動)
[2. 共有コンポーネントの使用](#2-共有コンポーネントの使用)
[3. 共通化](#3-共通化)
[4. 動的ページの作成](#4-動的ページの作成)

## 1. ページ間の移動
- next.jsでは、`[プロジェクト名]/pages`直下に`hoge.js`など各ページのjsファイルを作成することでページの追加ができる。
    - nextにおいて特別なディレクトリは、この`pages`と`static`ディレクトリ
    - その他のディレクトリは自由に設定できる

- ページ間の移動は、Linkコンポーネントを使う
    - 通常のアンカータグのみでのリンク移動ではだめ。
    - 目的のページは表示されるが、再読み込みされてしまうから。→SPAの意味がない

```jsx:js(index.js)
~
<div>
  <a href="/about">About Page</a>
</div>
~
```

↑こうではなく、こう↓  

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

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


## 2. 共有コンポーネントの使用
以下、indexページとaboutページの２ページがあるとする。
これらの中身を見ると、各ページへのリンクがあるヘッダー部分が共通である。

```jsx: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>
  );
}
```  

```jsx: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）  

```jsx: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ページは以下のように変更する。

```jsx:index.js
import Header from '../components/Header.js';

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

```jsx: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}` に入る。

```jsx: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/router`の `useRouter` はrouterオブジェクトを返す。
routerオブジェクトの `query` オブジェクトでクエリストリングを取得できる。


## 5. 動的ルーティング
[4. 動的ページの生成](#4-動的ページの作成)では以下のURLで動的ページを作成した。
`http://localhost:3000/post?title=hello-world`  
  
これをもっと綺麗なURLで実現したい。以下のような。
`http://localhost:3000/p/hello-world`

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

```jsx:[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ページは以下のようになる。

```jsx: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


##