1

I have a counter functional component, with 2 buttons: increment and decrement and currently, when they're clicked, the state changes. But I want the state to change as long as the mouse is over the element. (not like onMouseOver that executes the event if the mouse is over, and then again when you move the mouse out from the element and then hover on the element again). I want it to be a constant hover event.

Heres my counter code:

import React, { useState } from "react";
import "./styles.css";

export default function App() {

  const [counter, setCounter] = useState(0)

  return (
    <div className="App">
      <h1>{counter}</h1>
      <button onClick={() => setCounter(counter + 1)}>Increment</button>
      <button onClick={() => setCounter(counter - 1)} disabled={counter < 1 ? true : false}>Decrement</button>
    </div>
  );
}

I hope that makes sense! Thanks in advance.

Roy
  • 1,612
  • 2
  • 12
  • 38
  • https://upmostly.com/tutorials/react-onhover-event-handling-with-examples – Kaslie May 12 '20 at 07:35
  • 2
    Probably I would try with `onMouseDown`, `onMouseEnter`, `onMouseLeave` events based on this [SO question](https://stackoverflow.com/questions/29981236/how-do-you-hover-in-reactjs-onmouseleave-not-registered-during-fast-hover-ove). One addition is I would include a debounce into the event in order not to trigger several times in a second, refer to [this one](https://stackoverflow.com/questions/23123138/perform-debounce-in-react-js). – norbitrial May 12 '20 at 07:36
  • Thanks! I'll take a look at it. – Roy May 12 '20 at 07:39

1 Answers1

3

Here you go :

For that, you might need one state variable that start and stops the interval on mouse hover and out,

Run the below code snippet, hope that will clear your doubts.

const { useState , useEffect , useRef } = React;

const App = () => {

  const _intervalRef = useRef(null);
  const [startCounter,setStartCounter] = useState(false);
  const [counter,setCounter] = useState(0);

  useEffect(() => {
    if(startCounter) {
         _intervalRef.current = setInterval(() => {
          setCounter((counter) => counter+1);
      },250);
    } else {
      clearInterval(_intervalRef.current);
    }
    return () => clearInterval(_intervalRef.current);
  },[startCounter]);

  return (
    <div>
      <div onMouseOver={() => setStartCounter(true)} onMouseOut={() =>setStartCounter(false)}>
        HOVER ME TO START COUNTER : { counter }
      </div>

    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('react-root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react-root"></div>
Vivek Doshi
  • 56,649
  • 12
  • 110
  • 122