How to Change an Element's Style on Hover in React

Last updated on December 01, 2022
How to Change an Element's Style on Hover in React

To change an element's style on hover in React, set a className on the element, and style its :hover pseudo-class.

For example:

import './App.css';

export default function App() {
  return (
    <div>
      <div className="box">
        <p>Coding Beauty</p>
      </div>
    </div>
  );
}
.box {
  height: 100px;
  width: 100px;
  background-color: blue;
  color: white;
  font-weight: bold;
  padding: 8px;
  text-align: center;
}

.box:hover {
  background-color: yellow;
  color: black;
}
Hovering over the element changes its style.

We use the :hover pseudo-class to style an element when the user hovers over it with the mouse pointer.

Change element style on hover with inline styling

We can also change an element's style on hover using inline styles and the element's style prop. To do this, we need to create state that will determine whether the hover styles should be applied to the element or not. We also need to add event listeners for the mouseenter and mouseleave and change the state's value in them.

For example:

import { useState } from 'react';

export default function App() {
  const [hover, setHover] = useState(false);

  const handleMouseEnter = () => {
    setHover(true);
  };

  const handleMouseLeave = () => {
    setHover(false);
  };

  return (
    <div>
      <div
        style={{
          height: '100px',
          width: '100px',
          backgroundColor: hover ? 'yellow' : 'blue',
          color: hover ? 'black' : 'white',
          fontWeight: 'bold',
          padding: '8px',
          textAlign: 'center',
        }}
        onMouseEnter={handleMouseEnter}
        onMouseLeave={handleMouseLeave}
      >
        <p>Coding Beauty</p>
      </div>
    </div>
  );
}

We use the useState hook to create the boolean state variable that will determine whether the hover styles should be applied to the element or not. useState returns an array of two values. The first is a variable that stores the state, and the second is a function that updates the state when it is called.

We use the onMouseEnter prop to listen for the mouseenter event to detect when the mouse enters within the element's bounds.

Note: While we could also listen for the mouseover event to detect hover, this event is triggered on an element and every single one of its ancestor elements in the DOM tree (i.e. it bubbles) and this could cause serious performance problems in deep hierarchies. mouseenter doesn’t bubble so we can use it without worrying about this.

Similarly, we use the onMouseLeave prop to listen for the mouseleave to detect when the mouse leaves the element's bounds.

We use the ternary operator to conditionally set the style based on the boolean state.

Change element style on hover with custom component

If you frequently use the inline styles approach to change the element's style on hover, it will be better if you encapsulate the logic into a custom component, so you can reuse it in multiple places in your codebase and avoid unnecessary duplication.

Here's what such a component would like:

import { useState } from 'react';

export default function Hover({ children }) {
  const [hover, setHover] = useState();

  const handleMouseEnter = () => {
    setHover(true);
  };

  const handleMouseLeave = () => {
    setHover(false);
  };

  return (
    <div
      style={{ display: 'contents' }}
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
    >
      {children(hover)}
    </div>
  );
}

The Hover component takes a callback function as its child. It passes the state variable storing the hover state to this callback so that you can use it to change the style of the element returned from the callback. Hover calls the callback to render this element.

It wraps the element with a div, on which it listens for the mouseenter and mouseleave events to update the state variable. We set the display CSS property to contents on the wrapper because it plays no visual role on the page. It's only there for the hover detection.

Here's how we can use our custom Hover component.

import Hover from './Hover';

export default function App() {
  return (
    <div>
      <Hover>
        {(hover) => (
          <div
            style={{
              height: '100px',
              width: '100px',
              backgroundColor: hover ? 'yellow' : 'blue',
              color: hover ? 'black' : 'white',
              fontWeight: 'bold',
              padding: '8px',
              textAlign: 'center',
            }}
          >
            <p>Coding Beauty</p>
          </div>
        )}
      </Hover>
    </div>
  );
}
Coding Beauty Assistant logo

Try Coding Beauty AI Assistant for VS Code

Meet the new intelligent assistant: tailored to optimize your work efficiency with lightning-fast code completions, intuitive AI chat + web search, reliable human expert help, and more.

See also