React hover状态触发后所有链接都加类,如何仅作用于被hover的元素?
问题原因
你现在所有链接共用同一个isHovered布尔状态,只要状态变化所有链接都会同步应用类名,自然会出现全部一起切换的问题。你需要把状态改为存储「当前正在被hover的链接的唯一标识」,而不是全局的是否hover的布尔值。
修改方案
我们用路由的数组索引作为标识,做三处修改即可:
- 调整state的初始值,改为存储hovered的索引,初始为
null - 给鼠标进出事件传当前链接的索引参数,更新state时只记录当前hover的索引
- 给Link加类名时做判断:只有当前遍历项的索引和state里存的hovered索引一致时,才加
is-hovered类
修改后完整代码
import React from "react"; import "./nav.css"; import { Home } from "../pages/home"; import { Weather } from "../pages/weather"; import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom"; const routes = [ { path: "/", exact: true, main: (props) => <Home {...props} />, label: "Home", }, { path: "/weather", main: (props) => { return <Weather {...props} />; }, label: "Weather", }, ]; export class Nav extends React.Component { state = { // 改为存储当前hover的索引,初始为null hoveredIndex: null, }; // 事件接收索引参数,更新当前hover的索引 mouseEnterHandler = (index) => { this.setState({ hoveredIndex: index, }); console.log('I am in') } mouseLeaveHandler = () => { this.setState({ hoveredIndex: null, }); console.log('I am out') } render() { return ( <Router> <div className="container"> <div className="sidebar_container"> <ul className="sidebar"> { console.log(this.state.hoveredIndex) } { routes.map((route, i) => ( <li key={i}> <Link {/* 只有当前索引匹配才加is-hovered类 */} className={this.state.hoveredIndex === i ? "is-hovered" : ""} to={route.path} {/* 传入当前索引给事件处理函数 */} onMouseEnter={() => this.mouseEnterHandler(i)} onMouseLeave={() => this.mouseLeaveHandler()} > {route.label} </Link> </li> ))} </ul> </div> <div className="page_container"> <Switch> {routes.map((route, index) => ( <Route key={index} path={route.path} exact={route.exact} children={<route.main apiKey={this.props.apiKey} />} /> ))} </Switch> </div> </div> </Router> ); } }
拓展说明
如果你的路由数组后续可能会增删导致索引不稳定,也可以用路由的path作为唯一标识,逻辑和上面一致,只要把state里存的内容换成path,判断时对比path即可。
内容的提问来源于stack exchange,提问作者Manuel Abascal
相关产品推荐
相关产品推荐

