前言
在开发过程中我们往往会遇到像首页导航栏的需求,然而普通的依靠下标控制导航栏状态无法长久保持状态,用户一刷新就会导致标题栏又回到默认状态。
那么该怎么办呢?
我们可以使用监听路由的方式来完成导航栏的状态持久化。
在了解监听路由前我们先了解一下react-route的钩子函数
一、react-router-dom的钩子函数
react的路由钩子函数主要有四种:
useHistory
useLocation
useParams
useRouteMatch
但是使用这些钩子函数React版本必须>= 16.8
二、useLocation()
此钩子可以返回location表示当前URL对象
import React, { useEffect } from 'react'
import { useLocation } from 'react-router-dom';
function MyComponent() {
const location = useLocation();
useEffect(()=>{
console.log(location)
/* 结果:
{pathname: "/", search: "", hash: "", state: null, key: "t061zail"}
hash: ""
key: "t061zail"
pathname: "/"
search: ""
state: null
[[Prototype]]: Object
*/
},[location])
}
三、实际案例
我们通过绑定动态class和监听路由实现持久化的标题栏
怎么配置路由,本文不做过多介绍。
组件:
//引入工具
import React, { memo, useState, useEffect } from 'react'
import { NavLink, useLocation } from "react-router-dom";
// 引入css
import './style.less'
const ZZZAppHeader = memo(() => {
// 根据index激活class
const [linkIndex, setLinkIndex] = useState(null)
// 监听路径
const { pathname } = useLocation()
// 导航栏列表
const linkList = [
{title:'首页',path:'/'},
{title:'介绍',path:'/character'},
{title:'新闻',path:'/news'},
{title:'设定',path:'/world'},
]
// 选中工具
const switchLocation = (_pathname) => {
switch (_pathname) {
case '/':
setLinkIndex(0)
break;
case '/character':
setLinkIndex(1)
break;
case '/news':
setLinkIndex(2)
break;
case '/world':
setLinkIndex(3)
break;
default:
setLinkIndex(0)
break;
}
}
useEffect(() => {
// console.log(linkIndex);
switchLocation(pathname)
}, [pathname, linkIndex])
return (
<header className='header'>
<div className='header__navbar'>
<div className='header__navbar-links'>
{
linkList.map((item,index) => {
return (
<NavLink key={index} className={`header__navbar-link ${index === linkIndex ? 'header__navbar-link--active':''}`} to={item.path}>{item.title}</NavLink>
)
})
}
</div>
</div>
</header>
)
})
export default ZZZAppHeader
css:
.header {
position: fixed;
top: 0;
left: 0;
z-index: 99;
width: 100%;
height: 75px;
background-color: #000;
img {
width: 100%;
}
}
}
.header__navbar {
display: flex;
justify-content: flex-end;
align-items: center;
height: 100%;
white-space: nowrap;
.header__navbar-links {
display: flex;
align-items: center;
.header__navbar-link {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
min-width: 1.24rem;
height: .44rem;
padding: 0 .1rem;
margin-left: .6rem;
font-size: .2rem;
font-weight: bold;
text-align: center;
color: #787878;
border-radius: 1.2rem;
cursor: pointer;
transform: scale(1);
transition: background 500ms, color 500ms, transform 500ms;
}
.header__navbar-link:hover,
.header__navbar-link--active {
background-color: #fff;
color: #000;
transform: scale(1.12);
}
}
}