如何将 stopPropagation() 与 Next.js 一起使用?

Uri*_*evi 6 javascript reactjs next.js

我正在尝试使用 stopPropagation,以便在单击任何其他元素后我的下拉菜单将关闭。

当我尝试使用 stopPropagation 并更新布尔状态时,按钮重新渲染页面(将状态重置回“false”),而不是将状态更新为 true,并且无论如何它都会停留在“true”上。

我写了一个例子的代码:

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>
  );
}
Run Code Online (Sandbox Code Playgroud)

这个问题似乎出现在 Next.js 中

我用React应用程序编写了相同的代码,没有问题。

Next.js 代码和盒子链接

React 代码和盒子链接

编辑:

当您分叉 Next.js 沙箱项目时,一切都工作正常。(但它并不能解决我的原始代码的问题)。

任何人都知道为什么会发生这种情况?

Uri*_*evi 0

我确实找到了这个错误的修复程序,第一个评论我的人解决了这个问题。

我在代码中添加了事件侦听器的清理功能,它似乎解决了问题。

看起来 useEffect 内部的清理不仅是一个好的实践,而且是“必须的”。

由于清理 useEffect 重新渲染页面两次而不是三次,并且它阻止了导致问题的另一次渲染。

非常感谢任何试图提供帮助的人。

固定代码是:

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

  useEffect(() => {
    window.addEventListener("click", () => setState(false)); 

    return () => window.removeEventListener("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>
  );
}
Run Code Online (Sandbox Code Playgroud)

Next.js 沙箱链接