在我的Next.js应用程序中,我似乎无法访问窗口:

未处理的拒绝(ReferenceError):没有定义窗口

componentWillMount() {
    console.log('window.innerHeight', window.innerHeight);
}


当前回答

如果你使用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。

其他回答

这是我做过的一个简单的解决方法。

const runOnClient = (func: () => any) => {
  if (typeof window !== "undefined") {
    if (window.document.readyState == "loading") {
      window.addEventListener("load", func);
    } else {
      func();
    }
  }
};

用法:

runOnClient(() => {
// access window as you like
})

// or async
runOnClient(async () => {
// remember to catch errors that might be raised in promises, and use the `await` keyword wherever needed
})

这比typeof window !== "undefined"要好,因为如果你只是检查窗口不是undefined,如果你的页面被重定向到,它不会工作,它只在加载时工作一次。但是,即使页面被重定向到,这个解决方法也可以工作,而不仅仅是在加载时一次。

在类Component的构造函数中可以添加

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 = {}
        }
}

这将避免错误(在我的例子中,错误将在我单击重载页面后发生)。

我必须从URL访问哈希,所以我想到了这个

const hash = global.window && window.location.hash;

在刷新页面时,我也遇到了同样的问题(由于导入与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

对于这种情况,Next.js具有动态导入功能。

对于包含只在浏览器中工作的库的模块,建议使用动态导入。请参考