ReferenceError: document is not defined in Next.js while working with React Aria overlays
ReferenceError: document is not defined in Next.js while working with React Aria overlays
我正在学习 Next.js 网络开发,我遇到了 commerce, a boilerplate for e-commerce websites written in Next.js. As I was browsing through the code I found the Sidebar
component which uses React Aria 创建叠加层。
我想在我自己的项目中使用这部分,所以写了一个 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;
这个组件被加载到我的布局组件中,就像在 commerce project 中一样。
但是,当我尝试加载索引页时,出现以下错误:
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 | }
当我删除 OverlayContainer
组件时,它加载一切正常。我尝试更新我的依赖项,将更多代码与 Github 存储库进行比较,但到目前为止没有找到。
这里有什么问题?我该如何解决?我将 Next 10 与 React 17.0.1 一起使用。
发生这种情况是因为 Next JS 具有服务器端渲染。当您使用服务器端呈现时,没有浏览器。因此,没有任何变量 window 或文档。因此出现此错误。
您可以采取的解决方法是 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;
我正在学习 Next.js 网络开发,我遇到了 commerce, a boilerplate for e-commerce websites written in Next.js. As I was browsing through the code I found the Sidebar
component which uses React Aria 创建叠加层。
我想在我自己的项目中使用这部分,所以写了一个 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;
这个组件被加载到我的布局组件中,就像在 commerce project 中一样。 但是,当我尝试加载索引页时,出现以下错误:
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 | }
当我删除 OverlayContainer
组件时,它加载一切正常。我尝试更新我的依赖项,将更多代码与 Github 存储库进行比较,但到目前为止没有找到。
这里有什么问题?我该如何解决?我将 Next 10 与 React 17.0.1 一起使用。
发生这种情况是因为 Next JS 具有服务器端渲染。当您使用服务器端呈现时,没有浏览器。因此,没有任何变量 window 或文档。因此出现此错误。
您可以采取的解决方法是 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;