适配器

在您选择的 React 框架中使用 nuqs

从 2 版开始,您现在可以在以下 React 框架中使用 nuqs,通过用 NuqsAdapter 上下文提供者包装它:

Next.js

应用路由器

在您的根布局文件中,用 NuqsAdapter 组件包装您的 {children}

src/app/layout.tsx
import { NuqsAdapter } from 'nuqs/adapters/next/app'
import { type ReactNode } from 'react'

export default function RootLayout({
  children
}: {
  children: ReactNode
}) {
  return (
    <html>
      <body>
        <NuqsAdapter>{children}</NuqsAdapter>
      </body>
    </html>
  )
}

页面路由器

在您的 _app.tsx 文件中,用 NuqsAdapter 组件包装 <Component> 页面出口:

src/pages/_app.tsx
import type { AppProps } from 'next/app'
import { NuqsAdapter } from 'nuqs/adapters/next/pages'

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

统一(路由器无关)

如果您的 Next.js 应用同时使用应用路由器和页面路由器,并且适配器需要挂载在任一路由器上,您可以导入统一适配器,但代价是捆绑包大小略微增大(~100B)。

import { NuqsAdapter } from 'nuqs/adapters/next'

适配器的主要原因是向其他 React 框架开放 nuqs:

React SPA

示例,使用 Vite:

src/main.tsx
import { NuqsAdapter } from 'nuqs/adapters/react'

createRoot(document.getElementById('root')!).render(
  <NuqsAdapter>
    <App />
  </NuqsAdapter>
)

注意

由于此配置中没有已知的服务器,shallow: false 选项将无效。

有关一些选项,请参阅以下内容:

shallow: false 上进行完整页面导航

Introduced in version 2.4.0.

您可以指定一个标志,当更新配置了 shallow: false 的查询状态时执行完整页面导航,以通知 Web 服务器 URL 状态已更改,如果服务器需要它来服务器端渲染应用程序的其他部分而非静态 React 捆绑包:

src/main.tsx
createRoot(document.getElementById('root')!).render(
  <NuqsAdapter fullPageNavigationOnShallowFalseUpdates>
    <App />
  </NuqsAdapter>
)

这对于非 JavaScript 编写的服务器可能有用,例如 Django(Python)、Rails(Ruby)、Laravel(PHP)、Phoenix(Elixir)等…

Remix

app/root.tsx
import { NuqsAdapter } from 'nuqs/adapters/remix'

// ...

export default function App() {
  return (
    <NuqsAdapter>
      <Outlet />
    </NuqsAdapter>
  )
}

React Router v6

src/main.tsx
import { NuqsAdapter } from 'nuqs/adapters/react-router/v6'
import { createBrowserRouter, RouterProvider } from 'react-router-dom'
import App from './App'

const router = createBrowserRouter([
  {
    path: '/',
    element: <App />
  }
])

export function ReactRouter() {
  return (
    <NuqsAdapter>
      <RouterProvider router={router} />
    </NuqsAdapter>
  )
}

仅支持 BrowserRouter。未来可能支持 HashRouter(参见问题 #810),但不支持 MemoryRouter

React Router v7

app/root.tsx
import { NuqsAdapter } from 'nuqs/adapters/react-router/v7'
import { Outlet } from 'react-router'

// ...

export default function App() {
  return (
    <NuqsAdapter>
      <Outlet />
    </NuqsAdapter>
  )
}

弃用通知

通用导入 nuqs/adapters/react-router(指向 v6)已被弃用,并将在 nuqs@3.0.0 中移除。

请将您的导入固定到特定版本,例如:nuqs/adapters/react-router/v6nuqs/adapters/react-router/v7

主要区别在于 React Router 钩子导入的位置:v6 来自 react-router-dom,v7 来自 react-router

TanStack Router TanStack Router

src/routes/__root.tsx
import { NuqsAdapter } from 'nuqs/adapters/tanstack-router'
import { Outlet, createRootRoute } from '@tanstack/react-router'

export const Route = createRootRoute({
  component: () => (
    <>
      <NuqsAdapter>
        <Outlet />
      </NuqsAdapter>
    </>
  ),
})

TanStack Router 支持是实验性的,尚未涵盖 TanStack Start。

通过 validateSearch 进行类型安全的路由

TanStack Router 自带内置的类型安全搜索参数支持,其 API 很可能应在您的应用程序代码中使用以获得最佳 DX。

尽管如此,有时您可能需要导入使用 nuqs 的组件(来自 NPM 或共享库),并受益于 TanStack Router 的类型安全路由。

您可以通过 标准模式 支持来实现:

import { createFileRoute, Link } from '@tanstack/react-router'
import {
  createStandardSchemaV1,
  parseAsIndex,
  parseAsString,
  useQueryStates
} from 'nuqs'

const searchParams = {
  searchQuery: parseAsString.withDefault(''),
  pageIndex: parseAsIndex.withDefault(0),
}

export const Route = createFileRoute('/search')({
  component: RouteComponent,
  validateSearch: createStandardSchemaV1(searchParams, {
    partialOutput: true
  })
})

function RouteComponent() {
  // 像往常一样消费 nuqs 状态:
  const [{ searchQuery, pageIndex }] = useQueryStates(searchParams)
  // 但现在 TanStack Router 也了解它:
  return (
    <Link
      to="/search"
      search={{
        searchQuery: 'foo',
        // 注意:我们没有指定 pageIndex
      }}
    />
  )
}

请注意,partialOutput 标志允许为给定路由指定搜索参数的子集。它也不会自动在 URL 中反映这些搜索,更多遵循 nuqs 的行为。

注意事项

由于 TanStack Router 和 nuqs 在处理序列化和反序列化方面的差异(TanStack Router 中为全局,nuqs 中为每个键),仅支持 简单 状态类型以进行类型安全的链接。这些包括所有基于字符串的解析器(字符串、枚举、字面量)、基于数字的(整数、浮点数、数字字面量)、布尔值和 JSON。

提供简写键名的 urlKeys 功能由于类似原因也不支持。

测试

NuqsTestingAdapter 的文档位于 测试页面