react-router 路由
安装
npm
npm install react-router-dom@6 -S
yarn
yarn add react-router-dom@6 -S
设置
要让 React Router 在您的应用程序中工作,您需要在元素树的根部或附近渲染一个路由器元素。
根据您的应用程序运行的位置,我们提供了几种不同的路由器。
<BrowserRouter>或者<HashRouter>应该在 Web 浏览器中运行时使用(您选择哪一个取决于您喜欢或需要的 URL 样式)
<NativeRouter>应该在React Native应用程序中使用。
API 参考
<BrowserRouter>使用干净的 URL 将当前位置存储在浏览器的地址栏中,并使用浏览器的内置历史堆栈进行导航。
import * as React from "react";
import * as ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
<BrowserRouter>
{/* The rest of your app goes here */}
</BrowserRouter>,
root
);
<NavLink>是一种特殊的类型,<Link>它知道它是否“活跃”。这在构建导航菜单(如面包屑或一组选项卡)时很有用,
以根据<NavLink>组件的活动状态自定义组件的内容,这对于更改内部元素的样式特别有用。
<NavLink to="/" >
Home
</NavLink>
<Navigate>元件改变时,它呈现的当前位置。它是一个围绕 的组件包装器useNavigate,并接受与 props 相同的所有参数。
replace: 重定向
<Navigate to="/dashboard" replace={true} />
<Outlet>应该在父路由元素中使用An来呈现其子路由元素。这允许在渲染子路由时显示嵌套 UI。
如果父路由完全匹配,它将渲染子索引路由,如果没有索引路由,则不渲染。
<Outlet />
这个钩子返回当前location对象。如果您想在当前位置更改时执行一些副作用,这可能很有用。
import * as React from 'react';
import { useLocation } from 'react-router-dom';
function App() {
let location = useLocation();
React.useEffect(() => {
ga('send', 'pageview');
}, [location]);
return (
);
}
该useSearchParams钩子用于读取和修改当前位置的 URL 中的查询字符串。
useSearchParams返回一个包含两个值的数组:当前位置的搜索参数和一个可用于更新它们的函数。
import * as React from "react";
import { useSearchParams } from "react-router-dom";
function App() {
let [searchParams, setSearchParams] = useSearchParams();
function handleSubmit(event) {
event.preventDefault();
let params = serializeFormQuery(event.target);
setSearchParams(params);
}
return (
<div>
<form onSubmit={handleSubmit}>{/* ... */}</form>
</div>
);
}
该useParams钩子从当前 URL 返回一个由<Route path>. 子路由继承父路由的所有参数。
import * as React from 'react';
import { Routes, Route, useParams } from 'react-router-dom';
function ProfilePage() {
let { userId } = useParams();
}
function App() {
return (
<Routes>
<Route path="users">
<Route path=":userId" element={<ProfilePage />} />
<Route path="me" element={...} />
</Route>
</Routes>
);
}
该useNavigate钩子返回的功能,可以让一个表单提交后您导航程序。
import { useNavigate } from "react-router-dom";
function SignupForm() {
let navigate = useNavigate();
async function handleSubmit(event) {
event.preventDefault();
await submitForm(event.target);
navigate("../success", { replace: true });
}
return <form onSubmit={handleSubmit}>{/* ... */}</form>;
}
入口文件
App.js
import './App.css';
import {BrowserRouter, useLocation } from 'react-router-dom'
import RouterList from './routers/index';
import React from 'react'
import Tab from './components/common/tabbar'
function Breadcrumb() {
const location = useLocation();
var showTabs = true
if(location.pathname == '/' || location.pathname == '/user/base/index' || location.pathname == '/contact/contact/index'){
showTabs = true;
} else{
showTabs = false;
}
return (<div>{showTabs ? <Tab /> : ''}</div>);
}
class App extends React.Component {
render() {
return (
<BrowserRouter>
<RouterList/>
<Breadcrumb/>
</BrowserRouter>
);
}
}
export default App;
路由总入口文件
src/routers/index.js
import React from 'react'
import {Routes, Route, Outlet} from 'react-router-dom'
import AuthRouter from './auth'
import Home from '@/components/home.js'
const ModulesFile = require.context('./',true,/index.js$/)
const RouterMap = []
ModulesFile.keys().reduce((modules, modulePath) => {
const ModuleName = modulePath.replace(/^.\/(.*)\.js/,'$1')
if(ModuleName !== 'index')
{
const ModuleList = ModulesFile(modulePath)
RouterMap.push(...ModuleList.default)
}
return RouterMap
}, {})
class RouterList extends React.Component{
constructor(props)
{
super(props)
this.state = {}
}
render()
{
return (
<>
<Routes>
{/* 默认首页 */}
<Route path="/" element={<Home />}></Route>
<Route path="/" element={<><Outlet /></>}>
{
RouterMap.map((item, index) => {
return (
<Route key={index} path={item.path} element={<AuthRouter auth={item.auth} component={<item.component />}></AuthRouter>}>
{item.children &&
item.children.map((son, idx) => <Route key={idx} path={son.path} element={<AuthRouter auth={son.auth} component={<son.component />}></AuthRouter>}></Route>)
}
</Route>
)
})
}
</Route>
</Routes>
</>
)
}
}
export default RouterList
每个独立路由模块下面的入口文件index.js
src/routers/user/index.js
import { Outlet } from 'react-router-dom'
const ModulesFile = require.context('./',true,/.js$/)
const RouterMap = []
ModulesFile.keys().reduce((modules, modulePath) => {
const ModuleName = modulePath.replace(/^.\/(.*)\.js/,'$1')
if(ModuleName !== 'index')
{
const ModuleList = ModulesFile(modulePath)
RouterMap.push(...ModuleList.default)
}
return RouterMap
},{})
const layout = () => {
return (
<>
<Outlet />
</>
)
}
const RouterList = [
{
path: '/user',
component: layout,
children: RouterMap,
}
]
export default RouterList
独立模块的路由文件
src/routers/user/base.js
import profile from "@/components/user/profile"
import index from "@/components/user/index"
import login from "@/components/user/login"
const base = [
{
path: "base/index",
name: 'baseindex',
component: index,
auth: true
},
{
path: "base/profile",
name: 'profile',
component: profile,
auth: true
},
{
path: "base/login",
name: 'login',
component: login,
},
]
export default base