在我的 NextJS 应用中,我似乎无法访问window
未处理的拒绝(ReferenceError):未定义窗口
componentWillMount() {
console.log('window.innerHeight', window.innerHeight);
}
答案 0 :(得分:8)
将代码从componentWillMount()
移至componentDidMount()
:
componentDidMount() {
console.log('window.innerHeight', window.innerHeight);
}
在NextJS中,componentDidMount()
仅在window
和其他特定于浏览器的API可用的客户端上执行。来自NextJS wiki:
Next.js是通用的,这意味着它首先在服务器端执行代码, 然后是客户端。窗口对象仅存在于客户端,因此如果 您绝对需要在某些React组件中访问它,您 应该将该代码放在componentDidMount中。此生命周期方法将 仅在客户端上执行。您可能还需要检查是否 不是满足您需求的替代通用库。
同样,componentWillMount()
在React v17中将是deprecated,因此在不久的将来使用它实际上是不安全的。
答案 1 :(得分:3)
没有SSR
import dynamic from 'next/dynamic'
const DynamicComponentWithNoSSR = dynamic(
() => import('../components/hello3'),
{ ssr: false }
)
function Home() {
return (
<div>
<Header />
<DynamicComponentWithNoSSR />
<p>HOME PAGE is here!</p>
</div>
)
}
export default Home
答案 2 :(得分:3)
我必须从 URL 访问哈希,所以我想出了这个
const hash = global.window && window.location.hash;
答案 3 :(得分:1)
componentWillMount()
生命周期挂钩既可以在服务器上也可以在客户端上使用。如果您的服务器在页面投放期间不知道“窗口”或“文档”,建议将代码移至
解决方案1:
componentDidMount()</code>.
或者,解决方案2
如果这只是您要执行的操作,则可以编写如下内容:
componentWillMount() {
if (typeof window !== 'undefined') {
console.log('window.innerHeight', window.innerHeight);
}
}
答案 4 :(得分:1)
其他解决方案是使用process.browser
仅在客户端渲染期间执行命令。
if (process.browser) {
// client-side-only code
}
答案 5 :(得分:1)
对于这种情况,Next.js 有 Dynamic Import。
包含仅在浏览器中工作的库的模块,建议使用动态导入。 Refer
答案 6 :(得分:0)
在类组件的构造函数中,您可以添加
if (typeof window === 'undefined') {
global.window = {}
}
示例:
import React, { Component } from 'react'
class MyClassName extends Component {
constructor(props){
super(props)
...
if (typeof window === 'undefined') {
global.window = {}
}
}
这将避免该错误(在我的情况下,该错误将在单击页面的重新加载后发生)
答案 7 :(得分:0)
如果您使用反应钩,则可以将代码移至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
。
答案 8 :(得分:0)
当我在next.js中开发Web应用程序时遇到了同样的问题。这解决了我的问题,您必须在生命周期方法或React Hook中引用窗口对象。例如,假设我想用redux创建一个存储变量,并且在这个存储中我想使用Windows对象,我可以按照以下步骤进行操作:
let store
useEffect(()=>{
store = createStore(rootReducers, window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__())
}, [])
....
因此,基本上,当您使用窗口的对象时,请始终使用钩子或componentDidMount()生命周期方法进行播放
答案 9 :(得分:0)
发生错误是因为窗口尚不可用,而组件仍在安装中。组件挂载后可以访问窗口对象。
您可以创建一个非常有用的钩子来获取动态 window.innerHeight
或 window.innerWidth
const useDeviceSize = () => {
const [width, setWidth] = useState(0)
const [height, setHeight] = useState(0)
const handleWindowResize = () => {
setWidth(window.innerWidth);
setHeight(window.innerHeight);
}
useEffect(() => {
// component is mounted and window is available
handleWindowResize();
window.addEventListener('resize', handleWindowResize);
// unsubscribe from the event on component unmount
return () => window.removeEventListener('resize', handleWindowResize);
}, []);
return [width, height]
}
export default useDeviceSize
用例:
const [width, height] = useDeviceSize();
答案 10 :(得分:0)
日期:06/08/2021
检查窗口对象是否存在,然后按照代码进行操作。
function getSelectedAddress() {
if (typeof window === 'undefined') return;
// Some other logic
}