在我的Next.js应用程序中,我似乎无法访问窗口:
未处理的拒绝(ReferenceError):没有定义窗口
componentWillMount() {
console.log('window.innerHeight', window.innerHeight);
}
在我的Next.js应用程序中,我似乎无法访问窗口:
未处理的拒绝(ReferenceError):没有定义窗口
componentWillMount() {
console.log('window.innerHeight', window.innerHeight);
}
当前回答
我想把我觉得有趣的方法留给未来的研究人员。它使用了一个自定义钩子useEventListener,可以用于许多其他需求。
请注意,您需要对最初发布的内容进行一些更改,就像我在这里建议的那样。
所以它会像这样结束:
import { useRef, useEffect } from 'react'
export const useEventListener = (eventName, handler, element) => {
const savedHandler = useRef()
useEffect(() => {
savedHandler.current = handler
}, [handler])
useEffect(() => {
element = !element ? window : element
const isSupported = element && element.addEventListener
if (!isSupported) return
const eventListener = (event) => savedHandler.current(event)
element.addEventListener(eventName, eventListener)
return () => {
element.removeEventListener(eventName, eventListener)
}
}, [eventName, element])
}
其他回答
如果你使用React Hooks,你可以将代码移动到Effect Hook中:
import * as React from "react";
export const MyComp = () => {
React.useEffect(() => {
// window is accessible here.
console.log("window.innerHeight", window.innerHeight);
}, []);
return (<div></div>)
}
useEffect中的代码只在客户端(在浏览器中)执行,因此它可以访问window。
将代码从componentWillMount()移动到componentDidMount():
componentDidMount() {
console.log('window.innerHeight', window.innerHeight);
}
在Next.js中,componentDidMount()只在提供窗口和其他浏览器特定api的客户端上执行。来自Next.js wiki:
js是通用的,这意味着它首先在服务器端执行代码, 然后客户端。窗口对象只在客户端显示,因此if 你绝对需要在一些React组件中访问它 应该把该代码放在componentDidMount中。这个生命周期方法 只能在客户端执行。你可能还想检查一下是否有 是不是有其他的通用库可以满足你的需要。
同样,componentWillMount()将在React的v17中被弃用,因此在不久的将来使用它实际上可能是不安全的。
有点晚了,但您也可以考虑使用动态导入,从下一个关闭SSR的组件。
您可以在动态函数中修改组件的导入,然后使用返回值作为实际组件。
import dynamic from 'next/dynamic'
const BoardDynamic = dynamic(() => import('../components/Board.tsx'), {
ssr: false,
})
<>
<BoardDynamic />
</>
componentWillMount()生命周期钩子在服务器端和客户端都可以工作。在您的情况下,服务器在页面服务期间不知道窗口或文档,建议将代码移动到任何一个
解决方案1:
componentDidMount()
或者,方案2
如果它是你只想执行的东西,那么你可以这样写:
componentWillMount() {
if (typeof window !== 'undefined') {
console.log('window.innerHeight', window.innerHeight);
}
}
在刷新页面时,我也遇到了同样的问题(由于导入与SSR不能很好地工作)。
对我来说,固定它的是去发生这种情况的页面,并迫使导入是动态的:
import dynamic from 'next/dynamic';
const SomeComponent = dynamic(()=>{return import('../Components/SomeComponent')}, {ssr: false});
//import SomeComponent from '../Components/SomeComponent'
注释掉原始导入并动态导入组件将强制组件的客户端呈现。
动态导入在Nextjs的文档中有介绍: https://nextjs.org/docs/advanced-features/dynamic-import
我通过观看youtube视频找到了这个解决方案: https://www.youtube.com/watch?v=DA0ie1RPP6g