React路由
总的来讲,有两种管理路由的方式:
传统 router
之前,如果写React项目需要搭建一个路由系统,你很可能会这么写:
// index.js 中
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
)
// app.js 中
import React, { memo } from 'react'
import { Route, Routes,Navigate } from 'react-router-dom'
... // 导入组件
const App = memo(() => {
return (
<div>
<Routes>
<Route path='/home' element={<Home />}></Route>
<Route path='/about' element={<Login />}></Route>
</Routes>
</div>
)
})
export default App
上面的路由系统有一个问题:路由是通过标签形式管理,当有大量路由的时候,其易读性和架构就会变得不好,可以把这种路由模式类比XML,并与Json相比,他们在写法的优缺点上有明显的相似。
如果你写过VUE,应该还记得VUE中的路由并不是这样的,而是抽离出来,作为一个对象数组去管理路由。useRoutes
这个Hook就是将路由转换成了数组模式进行抽离管理。
useRoutes
1、管理路由
首先可以如图创建路由文件夹,管理路由文件。
在index.js
中进行路由管理,这个阶段不需要使用Hook:
/**
* 路由
*/
import Login from "../views/Login";
import Index from "../views/Index";
const routes = [
{
path: '/login',
element: <Login></Login>
},
{
path: '/index',
element: <Index></Index>
}
]
export default routes
如果你看过react-router
官方文档,注意有几个坑,目前官网还没有更改:
-
组件必须要使用标签格式,而不能直接使用导入的变量名:
使用<Login></Login>而不是使用`Login`
-
只能使用
element
申明路由使用的组件,而不能使用component
2、使用路由
来到app.js
import { useRoutes } from "react-router-dom";
import routes from "../router";
export default function App() {
// 导入路由
const elements = useRoutes(routes);
return <>{elements}</>;
}
使用很简单,只需要将刚刚的路由对象传入useRoutes
,就会返回一个保存有路由组件的变量,在需要使用的地方{elements}
导入即可。
这里需要注意的地方也就只有Hook需要在最外层使用。
3、额外需要做的
如果只经过上面两个步骤,可能会导致一个错误:
useRoutes() may be used only in the context of a <Router> component.
字面意识是没有包裹在<Router>
标签下。
解决:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './views/App';
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<>
<BrowserRouter>
<React.StrictMode>
<App></App>
</React.StrictMode>
</BrowserRouter>
</>
);
实际上需要导入BrowserRouter
标签,然后如图在index.js
入口文件写入。
4、路由重定向
react并不像VUE,在配置的时候提供redirect
字段重定向,我们需要重定向,如从/
到/index
怎么办:
const routes = [
{
path: '/',
element: <Navigate to='/index'></Navigate>
},
{
path: '/login',
element: <Login></Login>
},
{
path: '/index',
element: <Index></Index>
}
]