首先要声明的是 react-router 目前是beta版本,但是距离上次发布已经一年多没动静了,至于为什么迟迟没发布的原因可以看这个issue
本人的个人博客已经由v5升至v6版本,各位如果有新的项目,路由简单的情况下,还是建议尝尝鲜
个人觉得使用v6版本的好处有两个
1. 包的大小直接减半
底层依赖库history使用v5版本,而且v5版本 0 依赖
舍弃了path-to-regexp,内部实现了简单地转换规则
v5:
v6:
2. 更友好的路由守卫支持
v5在定义路由守卫Prompt的时候,只支持传入message,然后使用window.confirm弹框确认,如果想自定义弹框样式的话只能在router层传入getUserConfirmation,在v6中对这个功能进行了更好的支持,可以在组件层进行自定义
在v6中支持了这个功能:
function Home() {
const customConfirm = ({action, location, retry}) => {
console.log(action, location, retry);
if(window.confirm('hello'))retry()
}
useBlocker(customConfirm, true)
const navigate = useNavigate()
const click = () => {
navigate('/about')
}
return (
<div>
<button onClick={click}>about</button>
'home'
</div>
)
}
需要注意的是,在v6版本使用路由守卫钩子会自动添加 beforeunload 事件
关于v6版本的api,以及v5 => v6的升级,这里不再赘述,具体可以详细阅读官方文档: api、 升级
目前已知的一些坑给大家分享一下:
1. 由于v5版本是由class组件写的,v6版本改为了hooks,可能出现一些执行顺序的不一样,详情可以查看这个issue
2. useParams 只会返回当前路由的参数,不会返回子路由的参数,详情可以查看这个 issue
3. Route组件不在具有匹配路由能力,如:当前路由为 /home
在 v5中:
<Route path='/home' component={Home} />
<Route path='/about' component={About} />
此时会匹配 home route,展示home组件
但是如果在v6中使用这样的写法
<Route path='/home' element={<Home />} />
<Route path='/about' element={<About />} />
页面上home 和about组件都会展示
原因在于 v6 版本摘除了 Route的路由匹配能力:
v5:
v6:
所以在v6中Route组件是必须和Routes组件配合使用的,
借由这个问题引起的 组件树的变化,而导致的组件 重载或更新 就又是一些问题,所以在v5版本 Route组件没有和Switch组件配合使用的同学 想要升级的话还是考虑一下
此外给对源码感兴趣的同学推荐一下 v4 histroy 和 v5 react-router 本人的源码阅读笔记(虽然现在略微过时,但是熟知旧版本的源码,对于新版本的源码那还不是手到擒来)