上次介绍了react路由5.0的一些用法,这次介绍最新的路由6.0用法,相比5.0变化还不少。
路由5.0:https://blog.csdn.net/yoonerloop/article/details/124070341
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
一、Route、Routes
实现路由的定义,Route需要使用Routes进行包裹,不能单独使用,能够智能的匹配,自动实现类似5.0的Switch的功能:
<Routes>
<Route path={'/about'} element={<About/>}/>
</Routes>
二、Navigate
用于实现页面的跳转,可以替代Redirect,例如下面首次进如页面,默认打开about 页面,这是需要使用Navigate,通过to指定要默认打开的页面:
<Routes>
<Route path={'/about'} element={<About/>}/>
<Route path={'/home'} element={<Home/>}/>
<Route path={'/home'} element={<Demo/>}/>
<Route path={'/'} element={<Navigate to={'/about'}/>}/>
</Routes>
还可以实现自动的跳转,例如点击按钮每次+1当达到4的时候自动跳转:
<div>
<h2>我是当前Home的内容</h2>
{sum === 4 ? <Navigate to={'/about'} replace={false}/> : <h3>当前sum的值是:{sum}</h3>}
<button onClick={() => setSun(prevState => prevState + 1)}>点我+1</button>
</div>
默认replace是false,即push的形式,可以省略不写。
三、路由点击时候的默认效果
<NavLink className={(isActive) => {
console.log(isActive)
}} to={'/home'}>Home</NavLink>
<NavLink className={(isActive) => {
console.log(isActive)
}} to={'/about'}>About</NavLink>
点击home时候className会被自动回调,传递isActive,如果当前路由被触发,传递true,否则是false,可以在这里处理样式。
四、useRoutes
相当于对上面的内容的简化:
import React from 'react';
import {BrowserRouter, NavLink, Router,Route, Routes, Navigate, useRoutes} from "react-router-dom";
import About from "./components/about";
import Home from "./components/home";
/**
* 路由6.0
*/
export default function App(props) {
const element = useRoutes([
{
path: '/home',
element: <Home/>
},
{
path: '/about',
element: <About/>
},
{
path: '/',
element: <Navigate to={'/about'}/>
}
])
return (
<div>
{element}
<h4>内容</h4>
<NavLink to={'/home'}>Home</NavLink>
<NavLink to={'/about'}>About</NavLink>
</div>
);
}
显示的效果和上面的一致。
将路由单独抽取src/routes/index.js:
import Home from "../components/home";
import About from "../components/about";
import {Navigate} from "react-router-dom";
import React from "react";
export default [
{
path: '/home',
element: <Home/>
},
{
path: '/about',
element: <About/>
},
{
path: '/',
element: <Navigate to={'/about'}/>
}
]
在App.js中只剩余:
import React from 'react';
import {NavLink, useRoutes} from "react-router-dom";
import routes from './routes'
export default function App() {
const element = useRoutes(routes);
return (
<div>
{element}
<h4>内容</h4>
<NavLink to={'/home'}>Home</NavLink>
//end表示取消父级路由的高亮显示
//<NavLink to={'/about'} end>About</NavLink>
<NavLink to={'/about'}>About</NavLink>
</div>
);
}
五、嵌套路由
{
path: '/about',
element: <About/>,
children: [
{
path: 'hot',
element: <Hot/>
},
{
path: 'mine',
element: <Mine/>
}
]
}
export default function About(props) {
return (
<div>
<h2>About组件</h2>
<ul>
<li>
<NavLink to={'hot'}>热门</NavLink>
</li>
<li>
<NavLink to={'mine'}>我的</NavLink>
</li>
</ul>
{/*<h4>???</h4>*/}
{/*指定路由组件位置*/}
<Outlet/>
</div>
);
}
注意:二级路由不需要斜杠,否则找不到。
六、Outlet
用于占位,指定路由位置,例如上面的,点击hot或者mine,结果内容会显示在所在的位置,由于使用了路由表结构,如果不写,会显示不出来,同理,如下:
return (
<div>
<ul>
{
message.map((m) => {
return (
<li key={m.id}>
<Link to={'message'}>{m.title}</Link>
</li>
)
})
}
</ul>
<Outlet/>
</div>
);
message的li会显示在 所在的位置,由于使用了路由表结构,不写这个也显示不出来。
七、路由传参Params--useParams
在路由中使用params传递参数的时候时候。
(1)定义参数
export default [
{
path: '/home',
element: <Home/>
},
{
path: '/about',
element: <About/>,
children: [
{
path: 'hot',
element: <Hot/>,
children:[
{
path: 'message/:id/:title/:content',
element: <Message/>
}
]
},
{
path: 'mine',
element: <Mine/>
}
]
},
{
path: '/',
element: <Navigate to={'/about'}/>
}
]
(2)传递参数
<Link to={`message/${m.id}/${m.title}/${m.content}`}>{m.title}</Link>
(3)获取参数
export default function Message(props) {
const params = useParams()
//下面这种方式也能获取到,但是不常用
const a = useMatch('/about/hot/message/:id/:title/:content')
console.log(a)
return (
<div>
<h4>消息列表</h4>
<ul>
<li>{params.id}</li>
<li>{params.title}</li>
<li>{params.content}</li>
</ul>
</div>
);
}
八、路由传参search--useSearchParams
(1)定义参数
<Link to={`message?id=${m.id}&title=${m.title}&content=${m.content}`}>{m.title}</Link>
(2)获取参数
export default function Message(props) {
//setSearch:更新收到的参数
const [search, setSearch] = useSearchParams()
const id = search.get('id');
const title = search.get('title');
const content = search.get('content');
//不常用
const x = useLocation();
console.log(x)
return (
<div>
<h4>消息列表</h4>
<ul>
<li>{id}</li>
<li>{title}</li>
<li>{content}</li>
</ul>
</div>
);
}
九、路由传参state--useLocation
(1)定义参数
<Link to={'message'}
state={{
id: m.id,
title: m.title,
content: m.content
}}>{m.title}</Link>
(2)获取参数
export default function Message(props) {
const {state} = useLocation();
console.log(state)
return (
<div>
<h4>消息列表</h4>
<ul>
<li>{state.id}</li>
<li>{state.title}</li>
<li>{state.content}</li>
</ul>
</div>
);
}
十、页面跳转--非Link方式实现
Link、NavLink自带点击实现页面跳转的效果,如果想要自定义实现点击效果,然后跳转,Link,NavLink就不行了,需要使用到useNavigate。
const navigate = useNavigate()
function showDetail(m) {
console.log(8888)
//视图切换
navigate('message', {
replace: false,
state: {
id: m.id,
title: m.title,
content: m.content
}
})
}
showDetail为点击某个按钮需要跳转的方法。对应路由5的this.props.history.push和replace模式,详情参考前面的。
十一、页面前进后退--useNavigate
在路由5中使用withRouter实现全局页面的前进和后退功能,在路由6中统一使用useNavigate:
import React from 'react';
import {useNavigate} from "react-router-dom";
export default function Header(props) {
const navigate = useNavigate()
function back() {
navigate(-1)
}
function forward() {
navigate(1)
}
return (
<div>
<h2>头部</h2>
<button onClick={forward}>前进</button>
<button onClick={back}>后退</button>
</div>
);
}
十二、useInRouterContext
判断上下文是否处于路由环境中,返回true表示在,false表示不在,凡是被BrowserRouter、HashRouter包裹的都处于路由环境中。
十三、useNavigationType
判断当前页面是通过那种方式过来的。分为:push/replace/pop(刷新)。
十四、useOutlet
用来呈现当组件中渲染的嵌套路由:
const a = useOutlet();
console.log('useOutlet', a)
如果嵌套路由没生效a为null,如果已经挂载则展示路由对象。
四五、useResolvedPath
const x = useResolvedPath('/user/index.js?name=zhangsan&age=30')
console.log(x)
解析路径时候使用,可以解析系统的,也可以解析自定义的,不常用。