ReferenceError:使用 React Aria 覆盖时,Next.js 中未定义文档

Bas*_*Bas 8 javascript reactjs next.js react-aria

我正在学习 Next.js 进行 Web 开发,并且遇到了commerce,这是一个用 Next.js 编写的电子商务网站的样板。当我浏览代码时,我发现了使用React Aria来创建叠加层的Sidebar组件

我想在自己的项目中使用这部分,因此编写了一个Overlay也使用该OverlayContainer组件的组件。

import { useRef } from 'react';

import {
    useOverlay,
    useModal,
    OverlayContainer
} from '@react-aria/overlays';

const Overlay = ({ className, children, open = false, onClose }) => {
    const ref = useRef(null);

    const { modalProps } = useModal();

    let { overlayProps } = useOverlay({ onClose: onClose, open: open, isDismissable: true }, ref);
    return (
        <OverlayContainer>
            <div
                {...overlayProps}
                {...modalProps}
                ref={ref}
            >
                {children}
            </div>
        </OverlayContainer>

    );
};

export default Overlay;
Run Code Online (Sandbox Code Playgroud)

该组件被加载到我的 Layout 组件中,就像在commerce 项目中一样。但是,当我尝试加载索引页时,出现以下错误:

Server Error
ReferenceError: document is not defined

This error happened while generating the page. Any console logs will be displayed in the terminal window.
Source
pages/_document.tsx (90:33) @ Function.getInitialProps

  88 |     }
  89 | 
> 90 |     const { html, head } = await ctx.renderPage({ enhanceApp })
     |                                 ^
  91 |     const styles = [...flush()]
  92 |     return { html, head, styles }
  93 |   }
Run Code Online (Sandbox Code Playgroud)

当我删除该OverlayContainer组件时,它加载一切正常。我尝试更新我的依赖项,将更多代码与 Github 存储库进行比较,但到目前为止什么也没发现。

这里有什么问题?我该如何解决它?我正在使用 Next 10 和 React 17.0.1。

Kev*_*ang 2

您可以采取的解决方法isBrowser对于 NextJS 应用程序来说相当常见。

const isBrowser = typeof window !== "undefined";

使用它来有条件地渲染您的OverlayContainer.

import { useRef } from "react";

import { useOverlay, useModal, OverlayContainer } from "@react-aria/overlays";

/**
 * Utility to detect if you're on the server, or in the browser.
 */
const isBrowser = typeof window !== "undefined";

const Overlay = ({ className, children, open = false, onClose }) => {
  const ref = useRef(null);

  const { modalProps } = useModal();

  let { overlayProps } = useOverlay(
    { onClose: onClose, open: open, isDismissable: true },
    ref
  );
  return isBrowser ? (
    <OverlayContainer>
      <div {...overlayProps} {...modalProps} ref={ref}>
        {children}
      </div>
    </OverlayContainer>
  ) : null;
};

export default Overlay;

Run Code Online (Sandbox Code Playgroud)