React Router 6.x与React Router 5.x 版本相比,改变了什么?
-
内置组件: 移除Switch ,新增 Routes ;移除了 Redirect 组件,改用 Navigate 组件,新增Outlet等;
-
语法:component={About} 变为 element={}等。
-
新增hook:useParams、useNavigate、useMatch等。
…
一、默认路由配置
import './App.scss';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'
// BrowserRouter(需要后端配置路径), HashRouter(路径里面带'#')
import Home from './pages/Home/Home';
import Setting from './pages/Setting/Setting';
function App() {
return (
<div className="App">
<Router>
<header>
<ul>
<Link to="/home"><li>首页</li></Link>
<Link to="/setting"><li>设置</li></Link>
</ul>
</header>
{/* 注册路由 */}
<Routes>
<Route path="/" element={<Home />}></Route>
<Route path="/setting" element={<Setting />}></Route>
<Route path="*" element={<Home />} />
</Routes>
</Router>
</div>
);
}
export default App;
二、路由文件配置和懒加载
router/index.js
import React, { lazy } from 'react'
import { useRoutes } from 'react-router-dom'
import Home from '@pages/Home/Home'
// 路由懒加载
const lazyLoad = (path) => {
const Comp = lazy(() => import(`@pages/${path}`))
return (
<React.Suspense fallback={<>加载中...</>}>
<Comp />
</React.Suspense>
)
}
const routes = [
{
path: '/',
name: '开始',
element: <Home /> // 注意,这里必须要放组件<Home /> 而不是 Home
},
{
path: '/setting',
name: '高级',
element: lazyLoad('Setting/Setting')
},
{
path: '*',
element: lazyLoad('NotFound/NotFound')
}
]
const GetRoutes = () => {
return useRoutes(routes)
}
export default GetRoutes
在app.js中使用
import GetRoutes from './router/Index';
const App = () => {
return (
<div className="App">
<BrowserRouter >
<GetRoutes />
</BrowserRouter >
</div>
)
}
export default App;
三、嵌套路由和路由参数
import { Routes, Route, Outlet } from "react-router-dom";
// route默认前面加 / ,子路由前面没有加 / 会自动补上父级路由路径
function App() {
return (
<Routes>
<Route path="invoices" element={<Invoices />}>
<Route path=":invoiceId" element={<Invoice />} />
<Route path="sent" element={<SentInvoices />} />
</Route>
</Routes>
);
}
function Invoices() {
return (
<div>
<h1>Invoices</h1>
<Outlet />
</div>
);
}
function Invoice() {
let { invoiceId } = useParams();
return <h1>Invoice {invoiceId}</h1>;
}
function SentInvoices() {
return <h1>Sent Invoices</h1>;
}
*** 获取路径上(url?xxx= param )参数使用useSearchParams
import { useSearchParams } from 'react-router-dom'
const [searchParams, setSearchParams] = useSearchParams()
// 获取参数
searchParams.get('id')
// 判断参数是否存在
searchParams.has('id')
// 同时页面内也可以用set方法来改变路由
setSearchParams({"id":2})
四、重定向
<Route path="/about" element={<Navigate to="/aboutUs" replace />} />
五、路径别名设置
方法1: 控制台运行npm run eject 暴露webpack配置,在config目录下找到webpack.config.js文件下的alias配置,添加文件路径别名,然后重启项目
方法2: 不暴露webpack配置
- 运行“ yarn add react-app-rewired customize-cra ” ,
- 在根目录下创建 config-overrides.js
//config-overrides
const { override, addDecoratorsLegacy, addWebpackAlias } = require("customize-cra");
const path = require("path");
module.exports = override(
//增加路径别名的处理
addDecoratorsLegacy(),
addWebpackAlias({
'@': path.resolve(__dirname, './src')
})
);
- 在 tsconfig.json 文件中配置 baseUrl 和 paths
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": [
"src/*"
]
}
}
- 修改package.json中的scripts
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-app-rewired eject"
},
最后npm run start 重启项目。
六、Link组件必须在HashRouter或者BrowserRouter等Router组件里面使用,
否则会报错,把导航和路由注册分开,可以使用插槽。
App.tsx
import React from 'react';
import './App.css';
import {Link } from 'react-router-dom'
import IndexRouter from './router';
function Header () {
return (
<ul>
<li><Link to="/">List</Link></li>
<li><Link to="/detail">detail</Link></li>
</ul>
)
}
function App() {
return (
<div className="App">
<h3>app</h3>
<IndexRouter header={<Header />}></IndexRouter>
</div>
);
}
export default App;
router/index.jsx
import React, {Component,} from "react";
import ReactDOM from 'react-dom';
import { HashRouter,Routes,Route, Outlet } from "react-router-dom";
import List from '../views/List/List'
import Detail from '../views/Detail/Detail'
interface IProps {
header:string|JSX.Element
}
export default class IndexRouter extends Component<IProps, any>{
render () {
return (
<HashRouter>
{this.props.header}
<Routes>
<Route path="/" element={<List/>}/>
<Route path="/detail" element={<Detail/>}/>
</Routes>
</HashRouter>
)
}
}
参考链接
https://www.codetd.com/article/13663626
https://reactrouter.com/docs/en/v6