事件起因就是发现在浏览器点击后退后退的时候,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; })},[])