# 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 (
# |
Name |
Price |
Action |
{products.map((p, i) => (
{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();
```
## 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. 其他