reactjsreact-hooksuse-effectuse-stateevent-listener

When should I use useEffect hook instead of event listeners?


Should useEffect hook be used when it can be simplified using an event listener?

For example, in the below snippet code I use event listener to change some state and later useEffect hook to react to that state change and do some other thing

import { useEffect, useState } from "react";

export default function Foo() {
  const [isActive, setIsActive] = useState(true);

  useEffect(() => {
    // do any kind of business logic
  }, [isActive]);

  return (
    <>
      <button
        type="button"
        className="secondary"
        onClick={() => setIsActive(true)}
      >
        ACTIVATE
      </button>
      <button
        type="button"
        className="secondary"
        onClick={() => setIsActive(false)}
      >
        DEACTIVATE
      </button>
    </>
  );
}

Should I move useEffect logic to the onClick listeners?


Solution

  • In general I think if you can handle something in event handler you should do that. React docs don't advise to overuse useEffect, and also they suggest it is more for cases when you want to synchronize with some external system. More below:

    Docs:

    In React, side effects usually belong inside event handlers. Event handlers are functions that React runs when you perform some action—for example, when you click a button. Even though event handlers are defined inside your component, they don’t run during rendering! So event handlers don’t need to be pure.

    If you’ve exhausted all other options and can’t find the right event handler for your side effect, you can still attach it to your returned JSX with a useEffect call in your component. This tells React to execute it later, after rendering, when side effects are allowed. However, this approach should be your last resort.

    Docs suggest to use useEffect more in cases when you want to synchronize with some external system:

    You do need Effects to synchronize with external systems. For example, you can write an Effect that keeps a jQuery widget synchronized with the React state. You can also fetch data with Effects: for example, you can synchronize the search results with the current search query

    For a more in depth look I suggest you look at the docs.