5
4

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 3 years have passed since last update.

Next.jsのルーターにAnt Designのメニューと統合する方法

Last updated at Posted at 2021-07-20

この投稿では、Ant Designの<Menu>コンポーネントとNext.jsのルーターを統合して、次のことができるようにする方法を説明します。

  • サイドバーのメニューをクリックしたときに、Next.jsのルーターを使って画面遷移できるようにする
  • 現在アクセス中のURLに応じてメニューをハイライトする

次の動画のような振る舞いを作っていきます。

このチュートリアルは、

の続きです。

このチュートリアルで作ったプログラムの完成形はGitHubにアップしてあります。

実装後の動作デモはVercelにて見れます

Next.jsのルーターにAnt Designのメニューと統合する手順

まず、管理画面レイアウトAdminLayoutが全ページで適用されるようにしたいので、index.tsxから_app.tsxに移動します:

pages/_app.tsx
import "../styles/globals.css";
import type { AppProps } from "next/app";
import "antd/dist/antd.css";
import dynamic from "next/dynamic";

const AdminLayout = dynamic(() => import("../layouts/adminLayout"), {
  ssr: false,
});

export default function MyApp({ Component, pageProps }: AppProps) {
  return (
    <AdminLayout>
      <Component {...pageProps} />
    </AdminLayout>
  );
}

次に、AdminLayoutのメニューにNext.jsのルーターを組み込んでいきます:

// layouts/adminLayout.tsx
import {
  DashboardOutlined,
  LaptopOutlined,
  MenuFoldOutlined,
  MenuUnfoldOutlined,
  UserOutlined,
} from "@ant-design/icons";
import { Layout, Menu } from "antd";
import Link from "next/link";
import { useRouter } from "next/router";
import { ReactNode, useState } from "react";
import styles from "./adminLayout.module.css";

const { Header, Sider, Content } = Layout;

export default function AdminLayout({
  children,
}: {
  readonly children: ReactNode;
}) {
  const [collapsed, setCollapsed] = useState<boolean>(false);
  const router = useRouter();

  function toggle() {
    setCollapsed(!collapsed);
  }

  return (
    <Layout>
      <Sider trigger={null} collapsible collapsed={collapsed}>
        <div className={styles.logo} />
        <Menu theme="dark" mode="inline" selectedKeys={[router.pathname]}>
          <Menu.Item key="/" icon={<DashboardOutlined />}>
            <Link href="/">ダッシュボード</Link>
          </Menu.Item>
          <Menu.Item key="/users" icon={<UserOutlined />}>
            <Link href="/users">利用者</Link>
          </Menu.Item>
          <Menu.Item key="/equipments" icon={<LaptopOutlined />}>
            <Link href="/equipments">備品</Link>
          </Menu.Item>
        </Menu>
      </Sider>
      <Layout className="site-layout">
        <Header className={styles.siteLayoutBackground} style={{ padding: 0 }}>
          {collapsed ? (
            <MenuUnfoldOutlined className={styles.trigger} onClick={toggle} />
          ) : (
            <MenuFoldOutlined className={styles.trigger} onClick={toggle} />
          )}
        </Header>
        <Content
          className={styles.siteLayoutBackground}
          style={{
            margin: "24px 16px",
            padding: 24,
            minHeight: 280,
          }}
        >
          {children}
        </Content>
      </Layout>
    </Layout>
  );
}

ポイントとしては、

  • <Menu>コンポーネントのselectedKeysに現在ページのpathnameを与えるようにする
  • <Menu.Item>内のchildrenは、next/link<Link>コンポーネントにする

です。

あとは、3つの画面を実装していきます:

// pages/index.tsx
export default function Home() {
  return "ダッシュボード";
}

// pages/users.tsx
export default function Users() {
  return "利用者";
}

// pages/equipments.tsx
export default function Equipments() {
  return "備品";
}

これでAnt DesignのメニューとNext.jsのRouterが統合できました。

冒頭の動画ように、URLとメニューが連動するような動作になっているはずです。

5
4
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
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?