共计 1992 个字符,预计需要花费 5 分钟才能阅读完成。
事件起因就是发现在浏览器点击后退后退的时候,menu 的选中状态并不会自动更新,如下图所示:
想要的正确成果如下:
那话不多说,开始思考解决办法
应用的 ui 库是 antd 的,旁边的 menu 即 Menu,查阅官网相干组件材料可知,须要在 menu 组件上加上 selectedKeys
属性
本地的 menu
局部代码如下
<Menu
theme="dark"
mode="inline"
defaultSelectedKeys={[defaultSelectedKeys]}
onClick={onClick}
items={[
{
key: '/todolist',
icon: <UserOutlined />,
label: 'todolist',
},
{
key: '/form',
icon: <VideoCameraOutlined />,
label: 'Form',
},
{
key: '/test',
icon: <UploadOutlined />,
label: '各种测试',
},
]}
/>
把 defaultSelectedKeys
换成selectedKeys={[selectedKeys]}
<Menu
...
selectedKeys={[selectedKeys]}
/>
之所以这么做,是因为在加上了 selectedKeys
当前,实际上 defaultSelectedKeys
曾经齐全被前者代替了,后者要不要都不影响页面体现。
然而,很重要的一点就是换成了 selectedKeys
当前,须要手动在点击事件中更改其对应的值,不然选中的项永远不会扭转,如下图所示
另外,记得给 selectedKeys 加上初始值,不然页面第一次进来的时候是没有选中项的
替换完后,接下来就是须要获取当前页面上的 url 地址了,因为 selectedKeys
是依据 Menu
中items
的 key
来进行准确匹配的。
引入如下代码
import {useLocation} from 'react-router-dom'
const location = useLocation();
useEffect(()=>{window.onpopstate = function (e: PopStateEvent) {console.log('location',location)
};
return (()=>{window.onpopstate = null;})
},[])
useLocation
为 react-router-dom
自带的办法,返回以后路由的相干信息如下:
window.onpopstate
为浏览器点击后退后退的时候触发的办法,传递的参数不必管,在这里也用不上。
即,当初具体思路为:
在浏览器点击后退后退的时候,拿到以后浏览器的 url,返回给 selectedKeys
从而使 menu
组件可能失常选中对应的菜单项
然而,问题呈现了
在控制台打印console.log(
location,location.pathname)
能够看到,打印进去的 pathname
的值只会是第一个路由的值,再也不会变了,这就很奇怪了啊,明明 url 都变了,为什么这个值不会变了呢?
然而,当把 pathname
的值打印到页面上的时候,状况产生了变动
能够看到,页面上的pathname
是显示正确的,和 url 保持一致!
这阐明在事件中的 pathname
值固定为赋值时候的值,不会自动更新,而页面跳转时候的 pathname
会放弃更新!
解决办法:应用 useRef
对pathname
的值进行跟踪更新, 代码如下
import {useRef} from 'react';
const locationRef = useRef(location);
locationRef.current = location;
useEffect(()=>{window.onpopstate = function (e: PopStateEvent) {console.log('location',location.pathname,'locationRef.current',locationRef.current.pathname)
};
return (()=>{window.onpopstate = null;})
},[])
能够看到,应用useRef
打印进去的值是正确的
所以在 useEffect
中,加上赋值语句,所须要的成果就实现啦
useEffect(()=>{window.onpopstate = function (e: PopStateEvent) {setSelectedKeys(locationRef.current.pathname);
console.log('location',location.pathname,'locationRef.current',locationRef.current.pathname)
};
return (()=>{window.onpopstate = null;})
},[])