Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

147
Vistas
React hover state & class added to all link menus instead to only the hovered one

I'm trying to hover through each link & toggle the isHovered state on/off onMouseEnter & onMouseLeave which should toggle the class is-hovered on/off.

However, currently, the class is getting toggle in both links. How do I make sure it only changes in the hovered element?

This is my code:

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>
    );
  }
}

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

I have implemented your question using 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>
  );
}

You can use the same way using a class component.

This is the codesandbox to solution https://codesandbox.io/s/selectliitem-mxy7m

I hope this works for you!

about 4 years ago · Juan Pablo Isaza Denunciar

0

You need to create a wrapper component for Link to keep hover over information separately. The isHovered state being common was the issue.

I would create a component like below

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;

remove the following from the Nav 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')
  }

and use in the Nav component like below

         <div className="sidebar_container">
            <ul className="sidebar">
              {routes.map((route, i) => (
                <li key={i}>
                  <LinkWrapper route={route} />
                </li>
              ))}
            </ul>
          </div>
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda