学习中发现react-router5和6差异点较多,故在此记录.
1. 注册路由写法不同:
router@5: <Route path='home' component={home} />
router@6: <Route path='home' element={<home/>} />
2. 废弃掉 Switch 改为 Routes 用法一致
outer@5:
{/* Switch提高路由匹配效率, 非必填 */}
<Switch>
{/* 注册路由 */}
<Route path='/about' component={about}/>
<Route path='/home' component={home}/>
</Switch>
outer@6:
import {Route,Routes} from 'react-router'
// 所有的<Route>外层必须包裹一个<Routes>(不包裹会报错).
// <Route>相当于一个if语句,匹配了展示对应组件,不匹配则跳过
<Routes>
<Route path='/about' element={<About />} />
<Route path='/home' element={<Home/>}/> /}
</Routes>
3. 去除 Redirect 重定向 改用 Navigate
outer@5:
<Redirect to='/home' />
outer@6:
import { Navigate } from 'react-router-dom'
<Route path='/' element={<Navigate to='/home'>}
// Navigate 只要渲染就会引起视图的切换, 不写to会报错
4. NavLink 动态类名 的添加不同
outer@5:
<NavLink activeClassName='atguigu' to='/about'>about</NavLink>
outer@5:
<NavLink className={ ( {isActive} ) => isActive ? 'list-group-item atguigu' : 'list-group-item' } to='/home' />
// 可以抽成一个函数
<NavLink className={ computedClassName } to='/home' />
function computedClassName( {isActive} ){
return isActive ? 'list-group-item atguigu' : 'list-group-item'
}
5. useRoutes路由表 + 嵌套路由
router.js
const routes = [
{
path: '/about',
element: <About />
},
{
path: '/home',
element: <Home />,
children: [
{
path: 'message',
element: <Message />,
children: [
{
path:'detail',
element: <Detail/>
}
]
},
{
path: 'news',
element: <News />,
}
]
},
{
path: '',
element: <Navigate to='about' />
},
];
export default routes;
app.jsx中
import { useRoutes } from 'react-router-dom'
import routes from './routes'
const element = useRoutes(routes);
<div className="App">
{element}
</div>
home.jsx中
import { NavLink, Outlet } from 'react-router-dom'
export default class Item extends Component {
render() {
return (
<div>
home组件
<NavLink to='message'>message</NavLink>
<NavLink to='news'>news</NavLink>
{/* 指定路由组件呈现的位置,类似于Vue中的view-router */}
<Outlet/>
</div>
)
}
}
6.路由传参:
params形式:
第一步:
{list.map(({ id, title }) => (
<Link key={id} to={`detail/${id}/${title}`}>
{title}
</Link>
))}
第二步:
children: [
{
path:'detail/:id/:title',
element: <Detail/>
}
]
第三步:
import { useParams } from 'react-router-dom'
const { id,title } = useParams()
search形式:
第一步:
{list.map(({ id, title }) => (
<Link key={id} to={`detail?id=${id}&title=${title}`}>
{title}
</Link>
))}
第二步:
{
path:'detail',
element: <Detail/>
}
第三步:
// search有两种方法获取参数
import { useSearchParams, useLocation } from 'react-router-dom'
export default function Detail(){
const [search,setSearch] = useSearchParams()
const id = search.get('id')
const title = search.get('title')
// 通过这种方法获取和router5一样的用法
// const search = useLocation()
return (
<div>
我是details组件
传递过来的参数是{id}+{title}
<button onClick={() => setSearch('id=999&title=xixi')}>更改search传递过来的的值</button>
</div>
)
}
state形式:
第一步:
{list.map(({ id, title }) => (
<Link key={id} to='detail' state={{id,title}}>
{title}
</Link>
))}
第二步:
{
path:'detail',
element: <Detail/>
}
第三步:
import { useLocation } from 'react-router-dom'
export default function Detail(){
// 通过这种方法获取和router5一样的用法
const {state:{id,title}} = useLocation()
return (
<div>
我是details组件
传递过来的参数是{id}+{title}
</div>
)
}
7. 编程式路由导航
import { useNavigate } from 'react-router-dom'
const navigate = useNavigate()
// 编程式路由导航
function showDetail(id, title) {
// params和search 形式的跳转
navigate(`/detail/${id}/${title}`);
// state形式的跳转
navigate('detail',{
replace: false,
state: {
id,
title
}
})
}
function back () {
navigate(-1)
}
function forword () {
navigate(1)
}
{list.map(({ id, title }) => (
<p key={id} onClick={() => showDetail(id,title)}>{title}</p>
))}
<button onClick={back}>back</button>
<button onClick={forword}>forword</button>