ルーティング

タブリストボックスドロップダウンなど、多くのNextUIコンポーネントは、HTMLリンクとしてレンダリングできる柔軟性を提供します。このページでは、クライアントサイドルーティングと統合する方法について説明します。

はじめに

デフォルトでは、リンクは操作時にネイティブブラウザナビゲーションを実行します。ただし、多くのアプリやフレームワークでは、ページ間を移動する際にページ全体のリロードを回避するために、クライアントサイドルーターを使用します。NextUIProviderコンポーネントは、内部のすべてのNextUIコンポーネントが、提供されたクライアントサイドルーターを使用してナビゲートするように構成します。

アプリのルートで一度これをセットアップすると、hrefプロパティを持つNextUIコンポーネントはすべて、ルーターを使用して自動的にナビゲートします。

NextUIProviderのセットアップ

NextUIProviderは、navigateというプロパティを受け取ります。これは、クライアントサイドナビゲーションをプログラムで実行するために、ルーターから受け取った関数に設定する必要があります。次の例は、一般的なパターンを示しています。フレームワーク固有の例は以下に示します。

import * as React from "react";
// 1. import `NextUIProvider` component
import {NextUIProvider} from "@nextui-org/react";
function App() {
const navigate = useNavigateFromYourRouter();
// 2. Add the `navigate` function to the `NextUIProvider`
return (
<NextUIProvider navigate={navigate}>
<YourApplication />
</NextUIProvider>
);
}

Next.js

App Router

app/providers.tsx または app/providers.jsx (存在しない場合は作成) に移動し、next/navigation から useRouter フックを追加します。これは、ナビゲーションを実行するために使用できるルーターオブジェクトを返します。

useRouter を追加

// app/providers.tsx
'use client'
import {NextUIProvider} from '@nextui-org/react';
import {useRouter} from 'next/navigation'
export function Providers({children}: { children: React.ReactNode }) {
const router = useRouter();
return (
<NextUIProvider navigate={router.push}>
{children}
</NextUIProvider>
)
}

ルートへのプロバイダーの追加

次に、root レイアウトページに移動し、それを NextUIProvider でラップします。

// app/layout.tsx
import {Providers} from "./providers";
export default function RootLayout({children}: { children: React.ReactNode }) {
return (
<html lang="en" className='dark'>
<body>
<Providers>
{children}
</Providers>
</body>
</html>
);
}

: すでにアプリで NextUIProvider を設定している場合は、この手順をスキップしてください。

Pages Router

pages/_app.js または pages/_app.tsx (存在しない場合は作成) に移動し、next/router から useRouter フックを追加します。これは、ナビゲーションを実行するために使用できるルーターオブジェクトを返します。

// pages/_app.tsx
import type { AppProps } from 'next/app';
import {NextUIProvider} from '@nextui-org/react';
import {useRouter} from 'next/router';
function MyApp({ Component, pageProps }: AppProps) {
const router = useRouter();
return (
<NextUIProvider navigate={router.push}>
<Component {...pageProps} />
</NextUIProvider>
)
}
export default MyApp;

React Router

react-router-dom からの useNavigate フックは、ナビゲーションを実行するために使用できる navigate 関数を返します。

通常 App.jsx または App.tsx と呼ばれる App ファイルに移動し、useNavigate フックを追加し、navigate 関数を NextUIProvider に渡します。

// App.tsx or App.jsx
import {BrowserRouter, useNavigate} from 'react-router-dom';
import {NextUIProvider} from '@nextui-org/react';
function App() {
const navigate = useNavigate();
return (
<NextUIProvider navigate={navigate}>
{/* Your app here... */}
<Routes>
<Route path="/" element={<HomePage />} />
{/* ... */}
</Routes>
</NextUIProvider>
);
}
// main.tsx or main.jsx
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
)

useNavigate を呼び出し、NextUIProvider をレンダリングするコンポーネントが、React Router の内部コンテキストにアクセスできるように、ルーターコンポーネント (例: BrowserRouter) の内部にあることを確認してください。React Router の <Routes> 要素も NextUIProvider の内部で定義されている必要があります。これにより、レンダリングされたルート内のリンクがルーターにアクセスできるようになります。

Remix

Remix は内部で React Router を使用しているため、上記で説明したのと同じ useNavigate フックが Remix アプリでも機能します。NextUIProvider は、NextUI コンポーネントを含む各ページの root でレンダリングするか、すべてのページに追加するには app/root.tsx でレンダリングする必要があります。詳細については、Remix のドキュメントを参照してください。

// app/root.tsx
import {useNavigate, Outlet} from '@remix-run/react';
import {NextUIProvider} from '@nextui-org/react';
export default function App() {
const navigate = useNavigate();
return (
<html lang="en">
<head>
{/* ... */}
</head>
<body>
<NextUIProvider navigate={navigate}>
<Outlet />
</NextUIProvider>
{/* ... */}
</body>
</html>
);
}

使用例

アプリで NextUIProvider を設定したので、ページ間をナビゲートするために、TabsListbox、および Dropdown 項目の href プロパティを使用できます。

import {
Tabs,
Tab,
Listbox,
ListboxItem,
Dropdown,
DropdownTrigger,
DropdownMenu,
DropdownItem,
Button,
Link,
} from "@nextui-org/react";
function App() {
return (
<>
<Tabs aria-label="Navigation">
<Tab key="home" href="/home">Home</Tab>
<Tab key="about" href="/about">About</Tab>
</Tabs>
<Listbox aria-label="Navigation">
<ListboxItem key="home" href="/home">Home</ListboxItem>
<ListboxItem key="about" href="/about">About</ListboxItem>
</Listbox>
<Dropdown>
<DropdownTrigger>
<Button>Open</Button>
</DropdownTrigger>
<DropdownMenu aria-label="Navigation">
<DropdownItem key="home" href="/home">Home</DropdownItem>
<DropdownItem key="about" href="/about">About</DropdownItem>
</DropdownMenu>
</Dropdown>
<Link href="/home">Home</Link>
<Link href="/about">About</Link>
</>
);
}