网站字体大小是多少,建设一个网站需要什么安全设备,网页制作页面布局,网站有几类在用React开发时#xff0c;常用的路由是react-router #xff0c;但除此之外#xff0c;还有两个路由方案#xff0c;因为他们具备 react-router 没有的特性。
1. tanstack/router
1.1. 主要特性 100% 推断的 TypeScript 支持 类型安全的导航 嵌套路由和布局路由 内置…在用React开发时常用的路由是react-router 但除此之外还有两个路由方案因为他们具备 react-router 没有的特性。
1. tanstack/router
1.1. 主要特性 100% 推断的 TypeScript 支持 类型安全的导航 嵌套路由和布局路由 内置的路由加载器带有 SWR 缓存 为客户端数据缓存设计如 TanStack Query、SWR 等 自动路由预取 异步路由元素和错误边界 基于文件的路由生成 类型安全的 JSON 优先搜索参数状态管理 API 路径和搜索参数模式验证 搜索参数导航 API 自定义搜索参数解析器/序列化器支持 搜索参数中间件 路由匹配/加载中间件
1.2. 基础使用示例
import React, { StrictMode } from react
import ReactDOM from react-dom/client
import {Outlet,RouterProvider,Link,createRouter,createRoute,createRootRoute} from tanstack/react-routerimport { TanStackRouterDevtools } from tanstack/router-devtoolsconst rootRoute createRootRoute({component: () (div classNamep-2 flex gap-2Link to/ className{[.active]:font-boldHome/Link{ }Link to/about className{[.active]:font-boldAbout/Link/divhr /Outlet /TanStackRouterDevtools //),
})const indexRoute createRoute({getParentRoute: () rootRoute,path: /,component: function Index() {return (div classNamep-2h3Welcome Home!/h3/div)},
})const aboutRoute createRoute({getParentRoute: () rootRoute,path: /about,component: function About() {return div classNamep-2Hello from About!/div},
})const routeTree rootRoute.addChildren([indexRoute, aboutRoute])
const router createRouter({ routeTree })declare module tanstack/react-router {interface Register {router: typeof router}
}const rootElement document.getElementById(app)!
if (!rootElement.innerHTML) {const root ReactDOM.createRoot(rootElement)root.render(StrictModeRouterProvider router{router} //StrictMode,)
}
1.3. 原理浅析
tanstack/router 的实现原理与 react-router 类似关注的概念也完全相同可以理解为它站在 react-router 的肩膀上在某些细节上做了增强。
历史记录的实现https://github.com/TanStack/router/blob/main/packages/history/src/index.ts
Router 入口https://github.com/TanStack/router/blob/main/packages/react-router/src/link.tsx 2. wouter
2.1. 主要特性 最小依赖压缩后仅 2.1 KB对比 React Router 的 18.7 KB。 同时支持 React 和 Preact。 没有顶级的 Router / 组件它是完全可选的。 模仿 React Router 的最佳实践提供熟悉的 Route、Link、Switch 和 Redirect 组件。 拥有基于 hook 的 API用于更细粒度地控制路由useLocation、useRoute 和 useRouter。
2.2. 基础使用示例
import { Link, Route, Switch } from wouter;const App () (Link href/users/1Profile/LinkRoute path/aboutAbout Us/Route{/* Routes below are matched exclusively - the first matched route gets rendered*/}SwitchRoute path/inbox component{InboxPage} /Route path/users/:name{(params) Hello, {params.name}!/}/Route{/* Default route in a switch */}Route404: No such page!/Route/Switch/
);
2.3. 原理浅析
对于不同路由历史与定位信息的封装。 https://github.com/molefrog/wouter/blob/v3/packages/wouter/src/use-browser-location.js https://github.com/molefrog/wouter/blob/v3/packages/wouter/src/use-hash-location.js https://github.com/molefrog/wouter/blob/v3/packages/wouter/src/memory-location.js
import { parse as parsePattern } from regexparam;
import {useBrowserLocation,useSearch as useBrowserSearch,
} from ./use-browser-location.js;
import {useRef,useContext,createContext,isValidateElement,cloneElement,createElement as h,Fragment,forwardRef,useIsomorphicLayoutEffect,useEvent,
} from ./react-deps.js;
import { absolutePath, relativePath, unescape, stripQm } from ./paths.js;// 定义默认的 Router 对象
const defaultRouter {hook: useBrowserLocation,searchHook: useBrowserSearch,parser: parsePattern,base: ,ssrPath: undefined,ssrSearch: undefined,hrefs: (x) x,
};// 创建一个 Router 上下文提供给应用中的其他部分使用
const RouterCtx createContext(defaultRouter);// 获取最近的父级 router
export const useRouter () useContext(RouterCtx);// 创建一个参数上下文提供给 useParams() 使用以获取匹配的参数
const ParamsCtx createContext({});
export const useParams () useContext(ParamsCtx);// 内部版本的 useLocation 函数避免多余的 useRouter 调用
const useLocationFromRouter (router) {const [location, navigate] router.hook(router);return [unescape(relativePath(router.base, location)),useEvent((to, navOpts) navigate(absolutePath(to, router.base), navOpts)),];
};// 使用 useRouter 获取当前的 location
export const useLocation () useLocationFromRouter(useRouter());// 获取当前搜索参数并返回
export const useSearch () {const router useRouter();return unescape(stripQm(router.searchHook(router)));
};// 路由匹配函数
export const matchRoute (parser, route, path, loose) {const { pattern, keys } route instanceof RegExp? { keys: false, pattern: route }: parser(route || *, loose);const result pattern.exec(path) || [];const [base, ...matches] result;return base ! undefined? [true,() {const groups keys ! false? Object.fromEntries(keys.map((key, i) [key, matches[i]])): result.groups;let obj { ...matches };groups object.assign(obj, groups);return obj;},...(loose ? [$base] : []),]: [false, null];
};// 使用 useRouter 获取路由并匹配路径
export const useRoute (pattern) matchRoute(useRouter().parser, pattern, useLocation()[0]);// Router 组件用于提供自定义路由上下文
export const Router ({ children, ...props }) {const parent_ useRouter();const parent props.hook ? defaultRouter : parent_;let value;const [path, search] props.ssrPath?.split(?) ?? [];if (search) (props.ssrSearch search), (props.ssrPath path);props.hrefs props.hrefs ?? props.hook?.hrefs;let ref useRef({}),prev ref.current,next prev;for (let k in parent) {const option k base? parent[k] (props[k] || ): props[k] || parent[k];if (prev next option ! next[k]) {ref.current next { ...next };}next[k] option;if (option ! parent[k]) value next;}return h(RouterCtx.Provider, { value, children });
};// 渲染 Route 组件根据 props 提供不同渲染逻辑
const h_route ({ children, component }, params) {if (component) return h(component, { params });return typeof children function ? children(params) : children;
};// Route 组件用于匹配路径并渲染对应组件
export const Route ({ path, nest, match, ...renderProps }) {const router useRouter();const [location] useLocationFromRouter(router);const [matches, params, base] match ?? matchRoute(router.parser, path, location, nest);if (!matches) return null;const children base? h(Router, { base }, h_route(renderProps, params)): h_route(renderProps, params);return h(ParamsCtx.Provider, { value: params, children });
};