Estoy tratando de desplazarme por cada enlace y activar/desactivar el estado isHovered onMouseEnter & onMouseLeave , que debería activar is-hovered desactivar la clase.
Sin embargo, actualmente, la clase se alterna en ambos enlaces. ¿Cómo me aseguro de que solo cambie en el elemento flotante?
Este es mi código:
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 = { isHovered: false, }; mouseEnterHandler = () => { this.setState({ isHovered: !this.state.isHovered, }); console.log('I am in') } mouseLeaveHandler = () => { this.setState({ isHovered: !this.state.isHovered, }); console.log('I am out') } render() { return ( <Router> <div className="container"> <div className="sidebar_container"> <ul className="sidebar"> { console.log(this.state.isHovered) } { routes.map((route, i) => ( <li key={i}> <Link className={this.state.isHovered ? "is-hovered" : ""} to={route.path} onMouseEnter={() => this.mouseEnterHandler()} 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> ); } }He implementado tu pregunta usando React Hooks
import "./styles.css"; import { useState } from "react"; export default function App() { const [hover, setHover] = useState(false); const [selectedId, setSelectedId] = useState(-1); const toggleHover = (state) => { setHover(state); console.log(hover); }; const routes = [ { id: 0, name: "Fname" }, { id: 1, name: "Sname" } ]; return ( <div className="App"> <ul> {routes.map((item, key) => { return ( <li className={ selectedId === item.id && hover === true ? "isHovered" : "" } onMouseEnter={() => { toggleHover(true); setSelectedId(item.id); console.log(selectedId); }} onMouseLeave={() => { toggleHover(false); setSelectedId(-1); console.log(selectedId); }} > {item.name} {item.id} </li> ); })} </ul> </div> ); }Puede usar la misma manera usando un componente de clase.
Esta es la solución de codesandbox https://codesandbox.io/s/selectliitem-mxy7m
¡Espero que esto funcione para usted!
Debe crear un componente contenedor para que Link mantenga el cursor sobre la información por separado. El estado isHovered siendo común fue el problema.
Crearía un componente como el siguiente.
import { useState } from "react"; const LinkWrapper = ({ route }) => { const [isHovered, setHovered] = useState(false); return ( <Link className={isHovered ? "is-hovered" : ""} to={route.path} onMouseEnter={() => { setHovered(true); }} onMouseLeave={() => { setHovered(false); }} > {route.label} </Link> ); }; export default LinkWrapper; elimine lo siguiente del componente Nav
state = { isHovered: false, }; mouseEnterHandler = () => { this.setState({ isHovered: !this.state.isHovered, }); console.log('I am in') } mouseLeaveHandler = () => { this.setState({ isHovered: !this.state.isHovered, }); console.log('I am out') } y usar en el componente Nav como a continuación
<div className="sidebar_container"> <ul className="sidebar"> {routes.map((route, i) => ( <li key={i}> <LinkWrapper route={route} /> </li> ))} </ul> </div>