0

so This is my first component where I decelerate my routes. And I decided to make two navigation items. And made some styling. But i get the error to many re-renders. Because I try to add styling with hover effect. I don't want to use css. This is my code:

import React, { useState } from 'react';
import { BrowserRouter, Route, Switch, Link } from 'react-router-dom';
import logo from './logo.svg';
import './App.css';
import Products from './Screens/ProductsList';
import Preview from './Screens/Product';
import ProductCreate from './Screens/ProductCreate';
import ProductEdit from './Screens/ProductEdit';
import Home from './Screens/Home';

function App() {
  const [hover, setHover] = useState(false);
  return (
    <BrowserRouter>
      <div style={style.navigationContainer}>
        <Link
          onMouseEnter={setHover(true)}
          onMouseLeave={setHover(false)}
          style={hover ? style.hoverNavItem : style.navItem}
          to="/products"
        >
          Products List
        </Link>
        <Link
          onMouseEnter={setHover(true)}
          onMouseLeave={setHover(false)}
          style={hover ? style.hoverNavItem : style.navItem}
          to="/products/create"
        >
          Create Product
        </Link>
      </div>

      <Switch>
        <Route
          key="edit-product"
          path="/products/:id/edit"
          component={ProductEdit}
        ></Route>
        <Route
          key="add-product"
          path="/products/create"
          component={ProductCreate}
        ></Route>
        <Route key="preview" path="/products/:id" component={Preview}></Route>
        <Route key="products" path="/products" component={Products}></Route>
        <Route exact path="/" component={Home}></Route>
      </Switch>
    </BrowserRouter>
  );
}

export default App;
Emilis
  • 152
  • 1
  • 4
  • 21

2 Answers2

9

You need to pass a function to onMouseEnter and onMouseLeave that will call setHover function whenever those events are triggered

Change

onMouseEnter={setHover(true)}
onMouseLeave={setHover(false)}

to

onMouseEnter={() => setHover(true)}
onMouseLeave={() => setHover(false)}

Doing onMouseEnter={setHover(true)} will immediately call the setHover function and update the state instead of waiting for the onMouseEnter event. Consequently, your code is stuck in an infinite cycle of update state and re-render

Although, if you just want to apply some style on any element on hover, then doing it with CSS is much better than what you are trying to do. There's no need to re-render the component, when it is hovered on, just to update its style.

Also keep in mind that, since you are applying style to both Link components when hover is true, if you hover over one of the Link component, it will set hover to true and both Link components will be styled.

Yousaf
  • 27,861
  • 6
  • 44
  • 69
3

You need to trigger the function on event like this onMouseOver={() => {setHover(true}} sandbox here but with your technique you will have both link change when one is hover

Pierre Monier
  • 599
  • 2
  • 9