safe-routes
用於操作 React Router 應用程式中內部連結的型別安全輔助工具。
[!note] remix-routes 已重新命名為 safe-routes。如果您正在尋找 remix-routes 的文件,請參考這裡。
如果您要從 remix-routes 升級,請參考升級指南。
重點特色
安裝
$ npm add safe-routes
設定
將 safeRoutes
外掛程式添加到您的 vite.config.ts
import { defineConfig } from "vite";
import { reactRouter } from "@react-router/dev/vite";
import { safeRoutes } from 'safe-routes/vite';
export default defineConfig({
plugins: [
reactRouter(),
safeRoutes(),
],
});
支援的設定選項
strict: boolean
outDir: string
將 safe-routes typegen
新增到 typecheck
腳本
- "typecheck": "react-router typegen && tsc --build --noEmit"
+ "typecheck": "react-router typegen && safe-routes typegen && tsc --build --noEmit"
用法
型別化的 URL 生成
import { redirect } from 'react-router';
import { $path } from 'safe-routes'; // <-- Import magical $path helper from safe-routes.
export const action = async ({ request }) => {
let formData = await request.formData();
const post = await createPost(formData);
return redirect($path('/posts/:id', { id: post.id })); // <-- It's type safe.
};
附加查詢字串
import { $path } from 'safe-routes';
$path('/posts/:id', { id: 6 }, { version: 18 }); // => /posts/6?version=18
$path('/posts', { limit: 10 }); // => /posts?limit=10
// You can pass any URLSearchParams init as param
$path('/posts/delete', [['id', 1], ['id', 2]]); // => /posts/delete?id=1&id=2
型別化的查詢字串
藉由在路由檔案中匯出一個名為 SearchParams
的型別來定義查詢字串的型別
// app/routes/posts.tsx
export type SearchParams = {
view: 'list' | 'grid',
sort?: 'date' | 'views',
page?: number,
}
import { $path } from 'safe-routes';
// The query string is type-safe.
$path('/posts', { view: 'list', sort: 'date', page: 1 });
您可以將此功能與 zod 和 remix-params-helper 結合使用,以新增執行階段參數檢查
import { z } from "zod";
import { getSearchParams } from "remix-params-helper";
const SearchParamsSchema = z.object({
view: z.enum(["list", "grid"]),
sort: z.enum(["price", "size"]).optional(),
page: z.number().int().optional(),
})
export type SearchParams = z.infer<typeof SearchParamsSchema>;
export const loader = async (request) => {
const result = getSearchParams(request, SearchParamsSchema)
if (!result.success) {
return json(result.errors, { status: 400 })
}
const { view, sort, page } = result.data;
}
型別化的路由 ID
safe-routes 會匯出 RouteId
型別定義,其中包含您儲存庫中所有有效路由 ID 的列表,並具有一個輔助函式 $routeId
,可告訴 TypeScript 將給定的字串限制為有效的 RouteId 值之一。
import type { RouteId } from 'safe-routes';
import type { loader as postsLoader } from './_layout.tsx';
import { useRouteLoaderData } from 'react-router';
import { $routeId } from 'safe-routes';
export default function Post() {
const postList = useRouteLoaderData<typeof postsLoader>($routeId('routes/posts/_layout'));
}
支援 basename
開箱即用支援 Basename。如果您在 vite.config.ts
和 react-router.config.ts
中設定了 basename,safe-routes 將會自動將 basename 前置到生成的 URL 中。
// react-router.config.ts
import type { Config } from "@react-router/dev/config";
export default {
basename: "/blog",
} satisfies Config;
import { $path } from 'safe-routes';
$path('/posts/:id', { id: 6 }); // => /blog/posts/6