微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ReactDOM.createPortal() 在 next.js-typescript 中创建额外的空白 div

如何解决ReactDOM.createPortal() 在 next.js-typescript 中创建额外的空白 div

这是background.tsx:

interface BacdropProps {
  open?: string;
  onClick: () => void;
}

const Backdrop: React.FC<BacdropProps> = (props) => {
  let container: HTMLdivelement | null = null;
  if (typeof window !== "undefined") {
    const rootContainer = document.createElement("div");
    const parentElem = document.querySelector("#__next");
    parentElem?.insertAdjacentElement("afterend",rootContainer);
    // parentElem?.after(rootContainer) this gives me same issue
    container = rootContainer;
  }

  return container
    ? ReactDOM.createPortal(
        <div
          className={["backdrop",props.open ? "open" : ""].join(" ")}
          onClick={props.onClick}
        />,container
      )
    : null;
};

export default Backdrop;

这是 Backdoor.tsx 的 css

.backdrop {
  width: 100%;
  height: 100vh;
  background: rgba(0,0.75);
  z-index: 100;
  position: fixed;
  left: 0;
  top: 0;
  transition: opacity 0.3s ease-out;
  opacity: 1;
}

这是它的样子:

enter image description here

解决方法

您的代码将在每次 div.backdrop 重新渲染时创建 Backdrop。正确的方法应该是创建一次。正确的方法是使用 useEffect 来保证 ReactDOM.createPortal 只执行一次。并应用 useRef 以确保 container 在每次渲染中保持相同的实例。

const containerRef = useRef<HTMLDivElement>(null);

useEffect({
  // Will be execute once in client-side
  if (typeof window !== "undefined") {
    const rootContainer = document.createElement("div");
    const parentElem = document.querySelector("#__next");
    parentElem?.insertAdjacentElement("afterend",rootContainer);
    // parentElem?.after(rootContainer) this gives me same issue
    containerRef.current = rootContainer;
  }
},[window])

useEffect({
  // Will be execute once when containerRef is bind to <HTMLDivElement>
  if(containerRef.current) {
    ReactDOM.createPortal(
      <div
        className={["backdrop",props.open ? "open" : ""].join(" ")}
        onClick={props.onClick}
      />,containerRef.current
    )
  }
},[containerRef])

编辑

  1. 我删除了 window 中的存在检测,因为 useEffect 只会在客户端执行。

  2. 由于 ReactDOM.createPortal 将在根 div.backdrop (HTMLElement) 之外创建 div#next,我认为只需在 {{1} 中返回 null }} 组件很好。

Backdrop

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?