[A-00210] Journey to Frontend(Next.js)

フロントエンドが苦手なのでこの記事で練習&ポートフォリオを作成していきます。

・簡単なSPAを作ってみる

今回は学習記事に沿ってnpmではなくyarnを使ってビルドします。

下記コマンドを実行してyarn導入とNext.js/React, typescriptを導入してください。

npm -g i yarn
yarn add next react react-dom
yarn add -D typescript @types/node @types/react

package.jsonにスクリプトを追加しておく

{
  "scripts": {
    "dev": "next",
    "start": "next start",
    "build": "next build",
    "export": "next export"
  },
  "dependencies": {
    "next": "^14.2.5",
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  },
  "devDependencies": {
    "@types/node": "^20.14.12",
    "@types/react": "^18.3.3",
    "typescript": "^5.5.4"
  }
}

directoryを作成して実行ファイルも作成する

mkdir src && mkdir src/pages
touch src/pages/index.tsx
const Page = () => <div>Hello SPA!</div>;
export default Page;

下記のコマンドでhttpサーバーを起動します。

yarn next

下記の画面が表示されます。

上記のsrc/pagesフォルダ配下に置くことで動くのがPage Routerなるものらしいです。

現在はApp Routerが主流ですが、一旦学習のため、Page Routerの学習を進めます。

基本的にpagesディレクトリさえあればOKのようです。上記はsrc/pagesとしましたが、直下に./pagesでもOKです。

・Dynamic Routingについて

ファイル名を動的な値にして、リクエストURLで任意の値で受信し、表示します。

ディレクトリを作成、ファイルを作成します。

mkdir pages/blogs
touch pages/blogs/[number].tsx
import { useRouter } from "next/router"

export default function Page() {
    const router = useRouter();
    return (
        <p>
            Post: {router.query.number}
        </p>
    )
}

npm run devで起動し、下記のURLを打ち込むと、URLのパラメータ部分がそのままページに表示されます。

・(豆知識)PageRouterとApp Routerについて

page routerを使用する場合、pagesディレクトリ配下にファイルを作成します。

app routerを使用する場合、appディレクトリ配下にファイルを作成します。

これら二つが存在するとconflictを起こして起動に失敗します。

下記のようなディレクトリ構成でサーバーを起動させます。

pages/index.tsxとapp/page.tsxがconflictします。下記のようなエラー画面が表示されます。

・App Routerを使ってみる

app routerを使うにはappディレクトリにファイルを作成していきます。

下記のコマンドでプロジェクト配下にライブラリを作成します。

npm install next@latest react@latest react-dom@latest typescript@latest @types/react @types/node

ディレクトリを作成します。

mkdir app
cd app
touch page.tsx
import React from "react";

export default function Page() {
    return <h1>Hello, App Router!</h1>
}
npm run dev

下記の画面が表示されます。

・Page, Layoutについて学ぶ

ディレクトリ構成とURLは密接に関係しています。

appディレクトリ直下のpage.tsx(or index.tsx)ならデフォルトURL(URLパス無し)で表示されます。

app/dashboadディレクトリを作成するとURLは[/dashboad]になります。

import React from "react";

export default function Page() {
    return <h1>Here is inside of Dashboad.</h1>
}

実行すると下記のようになります。

layoutについて、next.jsを起動すると自動でappディレクトリ直下にlayout.tsxを作成してくれます。

これをrootLayoutというようです。app/dashboardに作成したlayout.tsxはこのrootlayoutを継承します。

下記のようなファイルを作成して実行します。

export const metadata = {
  title: 'Next.js',
  description: 'Generated by Next.js',
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}
export default function DashboardLayout({
    children,
} : {
    children: React.ReactNode
}) {
    return (
        <section>
            {/* Include shared UI here */}
                <nav>This is Navigation</nav>
                {children}
        </section>
    )
}

表示したら下記のようになります。

・Metadataについて

titleなどのメタデータの取り扱いは下記のようになる

import React from "react";

import { Metadata } from "next";

export const metadata: Metadata = {
    title: "Next.js",
}

export default function Page() {
    return <h1>Hello, App Router!</h1>
}

・Linkについて

app-routerによる別ページへのルーティングをLinkを使って行う際に下記ようなコードになる.補足だが複数のHTMLタグをリターンしたい時はJSXタグを用いる

import React from "react";

import { Metadata } from "next";
import Link from "next/link";

export const metadata: Metadata = {
    title: "Next.js",
}

export default function Page() {
    return (
    <>
    <h1>Hello, App Router!</h1>
    <Link href="/dashboard">GotoDashboard</Link>
    </>
    )
    
}

次にNavigationを作ってみます。三項演算が登場しますが、あまりよくわかってないのでLinkの使い方として一例程度にみてください。

'use client'

import { usePathname } from "next/navigation"
import Link from "next/link"

export default function Links() {
    const pathname = usePathname()

    return (
        <>
         <p>Current pathname: {pathname}</p>
          <nav>
            <ul>
                <li>
                    <Link className={`link ${pathname === '/' ? 'active' : ''}`} href="/">
                       Home
                    </Link>
                </li>
                <li>
                    <Link className={`link ${pathname === '/about' ? 'active' : ''}`} href="/about">
                     About
                    </Link>
                </li>
            </ul>
          </nav>
        </>
    )
}

・useRouterを使ってみる

useRouterを使って適当なページにhookしてみます。ちなみにnext/routerのuseRouterは古いらしいので間違えずにnext/navigationパッケージのuseRouterを使うことに注意してください。useRouterはクライアントサイドで動作するので[use client]を付けます。

'use client'

import { useRouter } from "next/navigation"

export default function Page() {
    const router = useRouter()

    return (
        <button type="button" onClick={() => router.push('/about')}>
            About
        </button>
    )
}

・Appendix

参考サイトはこちら

https://next-blog.croud.jp/contents/pFIUJ2UOv4qkdvKbgl5O

https://qiita.com/hiroki-yama-1118/items/b3388c5dcb155e2e367d

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

*