approuterになることによって変わること

# approuterになることによって変わること
Next.js 13.4以降、
approuterを導入することで、Next.jsアプリケーションの開発においていくつかの重要な変化がもたらされます。主な変更点は以下の通りです。

## 1. ルーティングの仕組み

### Pages Router
pages ディレクトリベースで、ファイルシステムがそのままURL構造に対応。（例：pages/about.js → /about）
### App Router
app ディレクトリベースで、コンポーネントを特別なファイル (page.js) にエクスポートしてルートを定義。より柔軟なルーティング構造やコンポーネント単位での機能分割が可能。
## 2. レイアウト

Pages Router: 共通レイアウトは _app.js で定義する必要がありました。
App Router: layout.js ファイルをディレクトリ内に配置するだけで、そのディレクトリ以下のすべてのルートで共有されるレイアウトを定義可能。ネストされたレイアウトもサポート。
## 3. データの取得

### Pages Router
getServerSideProps、getStaticProps、getStaticPaths などの専用関数を使用。
### App Router
より柔軟なデータ取得方法。
Server Components: サーバー上で実行されるコンポーネント内で async/await を使用して直接データを取得可能。
fetch APIの拡張: Next.jsの拡張された fetch API で、データのキャッシュや再検証を細かく制御可能。
Route Handlers: APIエンドポイントを app ディレクトリ内で直接定義可能。
## 4. Server Components

App Routerの大きな特徴。UIの一部をサーバー上でレンダリングし、クライアント側のJavaScript量を削減。初期ロード時間の改善やインタラクティブ性の向上に貢献。
## 5. Client Components

従来のReactコンポーネントは引き続き利用可能。クライアントサイドでJavaScriptを実行し、ステートやイベントハンドラーを持つ。'use client' ディレクティブをファイルの先頭に追加する必要あり。
## 6. コロケーション:

コンポーネント、データ取得ロジック、テストなどを同じディレクトリ内に配置しやすく、コードの整理や管理が容易に。
## 7. より細やかな制御:

ルーティング、データ取得、キャッシュ戦略など、アプリケーションの様々な側面において、より細やかな制御を開発者に提供。
## まとめ:

approuterにより、よりモダンで柔軟なNext.jsアプリケーション開発が実現します。Server Componentsによるパフォーマンス向上、強力なルーティングとレイアウト、洗練されたデータ取得などが主なメリットです。

## 以下使用例

Next.js データ取得方法の比較
Next.jsでは、Pages RouterとApp Routerでデータの取得方法が大きく異なります。以下に、それぞれの方法と、主な関数の対応についてまとめます。

Pages Router (pages ディレクトリ)
Pages Routerでは、ページコンポーネント内で特定の関数をエクスポートすることで、データの取得やレンダリング方法を制御していました。

getServerSideProps

　リクエストごとにサーバー側でデータを取得し、ページをレンダリングします。

　ユーザー認証が必要なページや、頻繁にデータが更新されるページに適しています。

　例:
```
export async function getServerSideProps(context) {
  const res = await fetch(`https://.../data`);
  const data = await res.json();
  return {
    props: { data },
  };
}
```
getStaticProps

　ビルド時にデータを取得し、ページを静的に生成します。

　ブログ記事や商品詳細ページなど、比較的更新頻度の低いページに適しています。

　オプションで revalidate を設定することで、バックグラウンドでページを更新できます (ISR: Incremental Static Regeneration)。

例:
```
export async function getStaticProps() {
  const res = await fetch(`https://.../data`);
  const data = await res.json();
  return {
    props: { data },
    revalidate: 60, // 60秒ごとに更新
  };
}
```
getStaticPaths

　getStaticProps と組み合わせて、動的なルート ([id].js など) の静的生成に必要なパスを定義します。

　例:
```
export async function getStaticPaths() {
  const res = await fetch(`https://.../ids`);
  const ids = await res.json();
  const paths = ids.map((id) => ({ params: { id: id.toString() } }));
  return {
    paths,
    fallback: false, // パスに含まれないIDへのアクセスは404
  };
}

export async function getStaticProps({ params }) {
  const res = await fetch(`https://.../data/${params.id}`);
  const data = await res.json();
  return {
    props: { data },
  };
}
```
App Router (app ディレクトリ)
App Routerでは、Server ComponentsとClient Componentsの概念が導入され、データの取得方法がより柔軟になりました。

Server Componentsでのデータ取得

　Server Components内で、async/await を使用して直接データを取得できます。

　これにより、サーバーサイドでデータを取得し、レンダリングに必要な最小限のHTMLをクライアントに送信できます。

　例:
```
import { db } from './lib/db'; // 例: Prismaクライアント

async function MyPage() {
  const data = await db.user.findMany(); // データベースからデータを取得
  return (
    <div>
      {data.map(user => (
        <div key={user.id}>{user.name}</div>
      ))}
    </div>
  );
}
export default MyPage;
```
fetch APIの拡張

　App Routerでは、Next.js拡張された fetch APIが提供され、キャッシュや再検証を細かく制御できます。

　例:
```
async function getData() {
  const res = await fetch('https://.../data', {
    next: { revalidate: 60 }, // 60秒ごとにキャッシュを更新
  });
  // レスポンスがOKでなければエラーをスロー
  if (!res.ok) {
    throw new Error('Failed to fetch data');
  }
  return res.json();
}

async function MyPage() {
  const data = await getData();
  // ...
}
```
generateStaticParams

　動的ルートの静的生成に必要なパスを定義します。getStaticPaths と似た役割を果たします。

例:
```
export async function generateStaticParams() {
  const res = await fetch('https://.../posts');
  const posts = await res.json();
  return posts.map((post) => ({
    id: post.id.toString(),
  }));
}

async function Page({ params }: { params: { id: string } }) {
  const res = await fetch(`https://.../posts/${params.id}`);
  const post = await res.json();
  // ...
}
```