How to use stopPropagation() with Next.js?

I am trying to use stopPropagation so my dropdown menu will close after I click on any other elements.

When I try to use stopPropagation & updating a boolean state the button re-render the page (which reset the state back to ‘false’) than updating the state to true and it stuck on "true" no matter what.

I wrote a code for an example:

import { useEffect, useState } from "react";

export default function IndexPage() {
  const [state, setState] = useState(false);

  useEffect(() => {
    document.body.addEventListener("click", () => {
      setState(false);
    });
  });

  const onButtonClick = (e) => {
    e.stopPropagation();
    setState(!state);
  };

  console.log(state);

  return (
    <div>
      <button onClick={onButtonClick}>Click</button>

      <h1>{state ? "true" : "false"}</h1>
    </div>
  );
}

This problem seems to appear only with Next.js

I wrote the same code with React app and there is no problem.

Next.js codesandbox link

React codesandbox link

6 thoughts on “How to use stopPropagation() with Next.js?”

  1. This is a strange one. But I think this might be related to Fast Refresh by Next.js and how in the codesandbox container the state is getting preserved for overtime edits as well so probably your e.stopPropagation when added to event handler didn’t trigger a state update and so the old handler for the button is still attached which means that the event listener on the body will keep on triggering as you click the button since our handler never got updated to factor in e.stopPropagation.

    When I fork your Next.js setup, everything works fine. Because it’s not an incremental change now. The container is rebuilt for me and doesn’t preserve any past state and so no stale event handlers or anything.

    Reply

Leave a Comment