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では参照できません