react-router v6 用起来

6,271 阅读2分钟

首先要声明的是 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 histroyv5 react-router 本人的源码阅读笔记(虽然现在略微过时,但是熟知旧版本的源码,对于新版本的源码那还不是手到擒来)