如何在Next.js中使用stopPropagation()?

isr3a4wc  于 2023-03-29  发布在  其他
关注(0)|答案(2)|浏览(111)

我正在尝试使用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>
  );
}

此问题似乎只在Next.js中出现
我用React app写了同样的代码,没有问题。
Next.js codesandbox link
React codesandbox link
编辑:
当你分叉Next.js沙盒项目时,一切都很好(但它并没有解决我原始代码的问题)。
有人知道为什么会这样吗?

sxissh06

sxissh061#

这是一个奇怪的问题。在codesandbox容器中,状态被保留以供超时编辑,并且不会导致任何重新渲染,因此可能您的e.stopPropagation在添加到事件处理程序时没有触发重新渲染。渲染,因此按钮的旧处理程序仍然附加,这意味着主体上的事件侦听器将在您单击按钮时继续触发,因为我们的处理程序从未更新到factor在e.stopPropagation中。
当我fork你的Next.js设置时,一切正常。因为它现在不是增量更改。容器为我重新构建,不保留任何过去的状态,因此没有陈旧的事件处理程序或任何东西。
测试这两种设置之间差异的最佳方法是查看当您从两者中删除e.stopPropagation行时,控制台是否记录任何值。您会看到Next.js没有,但React有。这意味着React的状态即使被保留,仍然会触发render等新的render,创建的事件处理程序知道:
嘿,我没有e.stopPropagation了,所以我的事件将冒泡

更新-Next.js容器似乎每次修改后都需要点击保存进行重新渲染。不要像React容器那样只依赖编辑。

mitkmikd

mitkmikd2#

我确实找到了这个bug的修复方法,第一个评论我的人解决了这个问题。
我在代码中添加了一个事件侦听器的清理程序,它似乎解决了这个问题。
在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>
  );
}

Next.js沙盒link

相关问题