路由

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/providers.tsxapp/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>
)
}

将 Provider 添加到根

现在,转到您的 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,则跳过此步骤。

页面路由器

转到页面/_app.jspages/_app.tsx(如果不存在,则创建它),并添加useRouter 钩子,该钩子来自 next/router,它返回一个路由器对象,可用于执行导航。

// 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 路由器

useNavigate 钩子来自 react-router-dom,它返回一个 navigate 函数,可用于执行导航。

转到通常称为 App.jsxApp.tsxApp 文件中,添加 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 的组件位于路由器组件(例如 BrowserRouter)中,以便它可以访问 React 路由器的内部上下文。React 路由器 <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,您可以在 TabsListboxDropdown 项中使用 href 属性在页面之间导航。

链接 组件还将使用 navigate 函数从 NextUIProvider 在页面之间导航。

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>
</>
);
}