# React路由 > React框架配套的路由系统插件 是 React Router。目前版本为V6。 ## 1. 基本使用 1. 创建路由实例 createBroswerRouter或者createHashRouter 2. 引入RouterProvider组件 3. 定义相关路由组件 ```jsx // 定义路由的模块 router/index.js import { createBrowserRouter } from 'react-router-dom'; import Home from '../pages/Home'; import About from '../pages/About'; const routes = [ { path: '/', element: , }, { path: '/about', element: , }, ]; const router = createBrowserRouter(routes); export default router; ``` ```jsx // 入口文件 import { RouterProvider } from 'react-router-dom'; import router from './router'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( ); ``` ## 2. 嵌套路由 实现分2步走: 1. 在指定父路由对象上添加children属性,值为路由对象数组; 2. 在父路由组件上通过Outlet组件来指定子路由组件的渲染位置 ```jsx // 定义嵌套子路由 const routes = [ { path: '/', element: , children: [ // 这是索引路由 { // path: '', index: true, element: , }, { path: 'about', element: , }, ], }, ]; ``` ```jsx // 父组件 -- 布局组件 import Header from '../components/Header'; import { Outlet } from 'react-router-dom'; function Layout() { return (
{/* 渲染子路由组件 */}
); } export default Layout; ``` ## 3. 动态路由 > 当实现一个类似详情页的需求时,我们可能会需要使用到动态路由 例如,在商品列表页中点击某一商品获取详情。 1. 假设 商品列表 对应的 路由是 `/products` 2. 需要单独页面显示某一商品的详情,此时 路由为这么定义:`/products/details/{product-id}` 因此这就是动态路由。 3. 定义路由时,使用":"去定义路由中的参数,即`{path: '/products/details/:productId'}` 4. 访问时,会自动匹配。成功后,会将路由参数与值解析出来,存储在params对象中 5. 通过路由Hook `useParams` 来获取上面解析后的路由参数对象 ```jsx // 列表页代码 function Products() { let [products] = useState(initialProducts); return (
{products.map((p, i) => ( ))}
# Name Price Action
{i + 1} {p.name} {p.price} 详情
); } export default Products; // 详情页代码 import { useParams } from 'react-router-dom'; function ProductDetail() { const { productId } = useParams(); // console.log(params); return (

详情页

您正在浏览的商品ID:{productId}

); } export default ProductDetail; ``` ## 4. 查询参数 > 在实际开发中,可以通过路由参数实现页面间数据传递;当然也可以通过查询参数。 下面代码演示,如果通过查询参数实现页面间数据传递: ```jsx {products.map((p, i) => ( {i + 1} {p.name} {p.price} {/* 1 路由参数 在页面间传递数据 */} {/* 详情 */} {/* 2 查询参数 在页面间传递数据 */} {/* 详情 */} 详情 ))} ``` ```jsx let [searchParams] = useSearchParams();
{/* Back */} { // go('/products'); // go({ pathname: '/products' }); go(-1); }} > Back

详情页

您正在浏览的商品ID:{searchParams.get('pid')}

``` ## 5. 页面导航 ### 5.1 声明式导航 1. Link组件 2. NavLink组件 NavLink在使用时,更容易实现选中效果。 ```jsx const handleLinkStyle = ({ isActive, isPending }) => isPending ? 'pending' : isActive ? 'actived' : 'link'; function Header() { return (
  • 主页
  • 关于
  • 商品
); } ``` ### 5.2 编程式导航 通过 `useNavigate()`Hook 获取到 `navigate`函数,接着通过调用navigate函数实现页面跳转。 ```jsx const navigate = useNavigate(); // navigate(to: Path, option?) // navigate(delta: number) navigate(-1) navigate(1) navigate('/login') navigate({pathname: '/login'}) navigate({pathname: '/login', search: '?id=1'}) navigate({pathname: '/login'}, {replace: true, state: {}}) ``` ## 6. 数据获取 > 在路由系统中,如何选择时机去获取数据? > > 我们知道在VueRouter中,已经提供了两种方式,都是用户能够接收并且体验良好的方案 > > 1. 在组件渲染后,添加Loading效果后去获取数据 > 2. 在路由开启导航时先去获取数据,这样组件渲染时就会连同数据一起渲染出来了 ### 6.1 Loading效果 ### 6.2 Data Loading 1. 在定义路由的时候,给路由对象添加loader数据加载器(值为函数),它会在在导航过程中启动数据加载。 2. 在路由组件中,通过`useLoaderData()`Hook函数来获取上面loader返回的数据 ## 7. 页面访问权限 ## 8. 其他