Vite + TanStack Router - 4. パラメータの取り扱い
今回はパスパラメータをサーチパラメータの取り扱いについてです。
パスパラメータ
createFileRoute
の引数(ルート名)はファイルを新規作成したタイミングで自動生成されます。
ルート名に$
で始まる部分がある場合、例えば/posts/$postId
のように記述すると、その部分がパスパラメータとなります。
パースされたパラメータはloader
やbeforeLoad
で{params}
として受け取ることができます。
beforeLoad: async ({ params }) => { // params.postId },
コンポーネントでパラメータを参照するには、Route.useParams()
フックを使用します。
const { postId } = Route.useParams()
また、グローバルにエクスポートされているuseParams()
フックを使用することも可能です。
const { postId } = useParams({ strict: false })
サーチパラメータ
クエリストリングはサーチパラメータとして自動的にパースされます。
パースされたパラメータはloaderDeps
やbeforeLoad
でsearch
として受け取ることができます。
たとえば post?sort=new
の場合以下のようになります。
beforeLoad: async ({ search }) => { // search.sort === 'new' },
コンポーネントでsearch
パラメータを参照するにはRoute.useSearch()
フックを使用します。
const { sort } = Route.useSearch()
また、グローバルにエクスポートされているuseSearch()
フックも利用可能です。
const search = useSearch({ strict: false, })
サーチパラメータのバリデーション
ルートのオプションにvalidateSearch
プロパティを追加することで、バリデーションを行うことができます。
type ProductSearch = { page: number, sort: 'newest' | 'price',}
export const Route = createFileRoute('/shop/products')({ validateSearch: (search: Record<string, unknown>): ProductSearch => { // サーチパラメータを検証し、型付きの状態に変換します return { page: Number(search?.page ?? 1), sort: (search.sort as ProductSearchSortOptions) || 'newest', } },})
zodを使用する場合は、zodのスキーマを変換するzodValidator
を使用します。valibot/ArkTypeの場合はアダプターは必要ありません。
import { fallback, zodValidator } from '@tanstack/zod-adapter'
const productSearchSchema = z.object({ page: fallback(z.number(), 1).default(1), sort: fallback(z.enum(['newest', 'oldest', 'price']), 'newest').default( 'newest', ),})
export const Route = createFileRoute('/shop/products/')({ validateSearch: zodValidator(productSearchSchema),})
navigateによるロケーションバーの同期
useNavigate()
フックから得られるnavigate
はsearch
属性と同じ引数を受け取ります。navigate
にsearch
を渡すことで、プログラムでロケーションバーを書き換えることが可能です。
router.navigate()
と<Navigate search />
も同様に使用できます。
searchミドルウェア
__root.tsx
でサーチパラメータを書き換えるミドルウェアを利用できます。
export const Route = createRootRoute({ validateSearch: zodValidator(searchSchema), search: { middlewares: [ ({search, next}) => { const result = next(search) return { rootValue: search.rootValue ...result } } ] }})
まとめ
- パラメータにはパスパラメータとサーチパラメータがあります
- パラメータはローダーとコンポーネントで参照できます
search
パラメータはloader
では参照できません