2024年8月22日、タイプセーフなURL状態管理ライブラリである nuqs のバージョン 2.5.0 がリリースされました。
このバージョンでは7つのベータリリースを経て、多くの便利な機能が追加されています。
特に注目すべき新機能を紹介すると次の通りです。
- 高頻度の入力に対するURL更新を制御する Debounce 機能
- コンポーネントの再レンダリングを最適化する Key Isolation
- 型推論と実行時バリデーションを提供する Standard Schema
- TanStack Router への実験的サポート
この記事では、これらの新機能について紹介します。
nuqs 2.5.0 で最も注目すべき機能の一つが、limitUrlUpdates
オプションによる Debounce 機能 です。この機能により、従来の throttleMs
オプションからより精密なURL更新制御が可能になりました。
検索フォームやフィルター機能において、ユーザーの入力ごとにURL更新が発生すると、高頻度なURL更新による処理負荷や、秒間数十回のAPI呼び出し発生、history: 'push'
使用時の履歴エントリ肥大化などの問題が生じることがあります。
nuqs では debounce()
と throttle()
の両方がサポートされており、用途に応じて使い分けることができます。Debounce は最後の入力を重視するため検索フォームに適しており、Throttle は継続的なフィードバックを提供するためスライダーやリアルタイム更新に適しています。
詳細な実装方法や具体的なコード例については、以下の記事で説明しています。
概要
Key Isolation は nuqs 2.5.0 で導入された パフォーマンス最適化機能 です。この機能により、コンポーネントは自分が管理するURL パラメータが変更された場合のみ再レンダリングされるようになります。
従来の実装では、どのURL パラメータが変更されても、nuqs を使用するすべてのコンポーネントが再レンダリングされる可能性がありました。Key Isolation はこの問題を解決し、大規模なアプリケーションでのパフォーマンスを改善します。
対応フレームワーク
Key Isolation は以下のフレームワークでサポートされています。
- React SPA
- React Router
- Remix
- TanStack Router
基本的な使い方
Key Isolation は自動的に動作するため、特別な設定は必要ありません。
function ProductFilters() {
const [category, setCategory] = useQueryState('category', parseAsString)
const [sort, setSort] = useQueryState('sort', parseAsString)
console.log('ProductFilters rendered')
return (
div>
select value={category || ''} onChange={(e) => setCategory(e.target.value)}>
option value="">全てoption>
option value="electronics">電子機器option>
select>
select value={sort || ''} onChange={(e) => setSort(e.target.value)}>
option value="">並び順option>
option value="price">価格順option>
select>
div>
)
}
パフォーマンス効果
Key Isolation により、無駄な再レンダリングを防げます。
従来の動作
/?category=electronics に変更
↓
nuqs を使う全てのコンポーネントが再レンダリング
- ProductFilters ✅(必要)
- 他のコンポーネント ❌(不要)
Key Isolation 有効時
/?category=electronics に変更
↓
category パラメータを使うコンポーネントのみ再レンダリング
- ProductFilters ✅(必要)
- 他のコンポーネント ⏸️(変更なし)
概要
Standard Schema は nuqs 2.5.0 で導入された バリデーション機能 です。この機能により、検索パラメータの定義から Standard Schema 互換のバリデーター を作成できるようになりました。
Standard Schema は、TypeScript のバリデーションライブラリ間で共通のインターフェースを提供する仕様です。nuqs がこの仕様に対応することで、tRPC や TanStack Router などの他のツールとの統合が簡素化されました。
基本的な使い方
import {
createStandardSchemaV1,
parseAsInteger,
parseAsString,
} from 'nuqs'
export const searchParams = {
searchTerm: parseAsString.withDefault(''),
maxResults: parseAsInteger.withDefault(10),
category: parseAsString
}
export const validateSearchParams = createStandardSchemaV1(searchParams)
tRPC との統合
Standard Schema により、tRPC のプロシージャで nuqs の検索パラメータ定義を直接使用できるようになりました。
import { router, publicProcedure } from './trpc'
import { validateSearchParams } from './search-params'
export const appRouter = router({
search: publicProcedure
.input(validateSearchParams)
.query(async ({ input }) => {
const { searchTerm, maxResults, category } = input
return await searchProducts({
query: searchTerm,
limit: maxResults,
category
})
}),
getProductCategories: publicProcedure
.query(async () => {
return await getCategories()
})
})
export type AppRouter = typeof appRouter
Standard Schema の効果
Standard Schema により、nuqs のパーサー定義から他のツールで利用可能なバリデーターを生成できるようになりました。
主要なメリット
-
ツール間の相互運用性
- tRPC、TanStack Form、TanStack Router など様々なライブラリで同じバリデーションロジックを再利用
- 「一度統合すれば、どこでもバリデーション」を実現
-
型安全性の一貫性
- フロントエンドのURL状態からバックエンドのAPIまで、型定義が自動的に連携
- TypeScript の型推論が各ツール間で共有される
-
開発体験の向上
- 各ライブラリ専用のアダプターを作成する必要がなくなる
- URL パラメータの定義を一箇所で管理し、複数の場所で活用可能
Standard Schema は標準仕様として策定されており、Zod、Valibot、ArkType などの主要なバリデーションライブラリが共通インターフェースを実装することで、エコシステム全体の統一を図っています。
nuqs 2.5.0 では TanStack Router への実験的サポートが追加されました。この機能は現在ベータ段階であり、補完的な機能として位置づけられています。
注意点
このサポートは nuqs を使用する外部ライブラリとの互換性 を目的としており、TanStack Router アプリ自体では通常必要ありません。TanStack Router は既に優れた型安全なURL状態管理APIを提供しているため、通常はそちらを使用するのが良いです。
参考: https://x.com/nuqs47ng/status/1959166202036490354
セットアップ
nuqs を使用するには、他のフレームワークと同様に専用のアダプターを設定します。
import { NuqsAdapter } from 'nuqs/adapters/tanstack-router'
import { Outlet } from '@tanstack/react-router'
export default function App() {
return (
NuqsAdapter>
Outlet />
NuqsAdapter>
)
}
基本的な使い方
TanStack Router では、createStandardSchemaV1
を使用してルートの検索パラメータバリデーションと統合できます。
import { createFileRoute } from '@tanstack/react-router'
import { useQueryState, parseAsString, parseAsInteger, createStandardSchemaV1 } from 'nuqs'
const searchParams = {
q: parseAsString.withDefault(''),
page: parseAsInteger.withDefault(1)
}
export const Route = createFileRoute('/search')({
validateSearch: createStandardSchemaV1(searchParams, { partialOutput: true }),
component: SearchPage
})
function SearchPage() {
const [query, setQuery] = useQueryState('q', parseAsString.withDefault(''))
const [page, setPage] = useQueryState('page', parseAsInteger.withDefault(1))
return (
div>
input value={query} onChange={(e) => setQuery(e.target.value)} />
p>ページ: {page}p>
div>
)
}
TanStack Router サポートは、nuqs の主要機能に加えてさらなる選択肢を提供する補完的な機能として開発が続けられています。
nuqs 2.5.0 では、上記の主要機能以外にも多くの改善が行われました。
Const modifier for literal parsers
parseAsStringLiteral
で const 修飾子がサポートされ、より正確な型推論が可能になりました。
const statusParser = parseAsStringLiteral(['draft', 'published', 'archived'])
const statusParser = parseAsStringLiteral(['draft', 'published', 'archived'] as const)
const [status, setStatus] = useQueryState('status', statusParser)
これにより、より正確な型推論により開発体験が向上しました。
Enhanced default options for NuqsAdapter
NuqsAdapter
でグローバルなデフォルトオプションを設定できるようになりました。
import { NuqsAdapter } from 'nuqs/adapters/next/app'
export default function RootLayout({ children }) {
return (
html>
body>
NuqsAdapter
defaultOptions={{
history: 'push',
shallow: false,
scroll: true,
clearOnDefault: true
}}
>
{children}
NuqsAdapter>
body>
html>
)
}
これにより、アプリケーション全体で一貫したオプションを適用できます。
パフォーマンス最適化
バンドルサイズの最適化
nuqs 2.5.0 では ゼロランタイム依存 を維持しながら、バンドルサイズを 5.5KB 未満 に抑えています。
[email protected]: ~6.2KB (gzipped)
[email protected]: ~5.4KB (gzipped) ⬇️ 13% 削減
Tree Shaking の改善
tree shaking の改善により、使用していない機能がバンドルから除外されるようになりました。
import { parseAsString, parseAsInteger } from 'nuqs'
API の改善
defaultRateLimit の導入
カスタムレート制限を無効化し、デフォルトの動作に戻すための defaultRateLimit
が追加されました。
import { debounce, defaultRateLimit } from 'nuqs'
const [search, setSearch] = useQueryState('q', {
limitUrlUpdates: debounce(1000)
})
const handleSubmit = () => {
setSearch(value, {
limitUrlUpdates: defaultRateLimit
})
}
urlKeys の型改善
urlKeys
オプションの型推論が改善され、より安全なコードが書けるようになりました。
import { type UrlKeys } from 'nuqs'
const parsers = {
latitude: parseAsFloat.withDefault(35.6762),
longitude: parseAsFloat.withDefault(139.6503)
}
const urlKeys: UrlKeystypeof parsers> = {
latitude: 'lat',
longitude: 'lng',
}
Next.js 15.5 Typed Routes 対応
nuqs 2.5で追加された機能というわけではありませんが、Next.js 15.5 で導入されたtyped routes 機能に向けて、公式XでcreateTypedLink()
ユーティリティ関数がポストされました。この関数により、型安全なリンク生成が可能になります。
これらの改善により、nuqs 2.5.0 は より安定、高速、型安全 なライブラリになりました。
nuqs 2.5.0 は、URL状態管理ライブラリとしての機能性を大きく向上させるアップデートです。このリリースにより、開発者はより型安全でパフォーマンスに優れたWebアプリケーションを構築できるようになりました。
以上です!
Views: 0