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

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

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


当前回答

有史以来最好的解决方案 从'next/dynamic'导入dynamic; const Chart = dynamic(()=> import('react-apexcharts'), { ssr:假的, })

其他回答

我在一个自定义钩子中包装了一般的解决方案(if (typeof window === 'undefined')返回;),这让我非常满意。它有一个类似的界面来反应useMemo钩子,我真的很喜欢。

import { useEffect, useMemo, useState } from "react";

const InitialState = Symbol("initial");

/**
 *
 * @param clientFactory Factory function similiar to `useMemo`. However, this function is only ever called on the client and will transform any returned promises into their resolved values.
 * @param deps Factory function dependencies, just like in `useMemo`.
 * @param serverFactory Factory function that may be called server side. Unlike the `clientFactory` function a resulting `Promise` will not be resolved, and will continue to be returned while the `clientFactory` is pending.
 */
export function useClientSideMemo<T = any, K = T>(
  clientFactory: () => T | Promise<T>,
  deps: Parameters<typeof useMemo>["1"],
  serverFactory?: () => K
) {
  const [memoized, setMemoized] = useState<T | typeof InitialState>(
    InitialState
  );

  useEffect(() => {
    (async () => {
      setMemoized(await clientFactory());
    })();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, deps);

  return typeof window === "undefined" || memoized === InitialState
    ? serverFactory?.()
    : memoized;
}

使用的例子:

我使用它来动态导入与next.js中的SSR不兼容的库,因为它自己的动态导入只与组件兼容。

  const renderer = useClientSideMemo(
    async () =>
      (await import("@/components/table/renderers/HighlightTextRenderer"))
        .HighlightTextRendererAlias,
    [],
    () => "text"
  );

正如你所看到的,我甚至实现了一个回退工厂回调,所以你可以提供一个结果时,最初呈现在服务器上。在所有其他方面,这个钩子应该表现类似于react useMemo钩子。接受反馈。

有史以来最好的解决方案 从'next/dynamic'导入dynamic; const Chart = dynamic(()=> import('react-apexcharts'), { ssr:假的, })

对于那些不能使用hook的人(例如,函数组件):

使用setTimeout(() => yourFunctionWithWindow());将允许它获得窗口实例。我想只是还需要一点时间来加载。

日期:06/08/2021

检查窗口对象是否存在,然后跟随代码进行操作。

 function getSelectedAddress() {
    if (typeof window === 'undefined') return;

    // Some other logic
 }

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

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