You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js使用react-globe报错“window is not defined”求助

Next.js 集成 react-globe 时出现 "window is not defined" 问题的解决方法

问题背景

我在 Next.js(React)项目中尝试集成 react-globe 组件,项目依赖如下:

{
  "@next/font": "^13.0.5",
  "eslint-config-next": "13.0.4",
  "next": "13.0.4",
  "react": "18.2.0",
  "react-dom": "18.2.0",
  "sharp": "^0.31.2",
  "three": "0.109.0",
  "react-globe": "5.0.2",
  "es6-tween": "5.5.10"
}

已添加"use client"指令,但页面渲染空白,控制台提示 "window is not defined" 错误,当前代码如下:

"use client";

import ReactGlobe from "react-globe";

import markers from "./markers";
import markerRenderer from "./markerRenderer";

const options = {
    markerRenderer,
};

export default function App() {
    return (
        <div className="App">
            <ReactGlobe
                height="100vh"
                globeTexture="https://raw.githubusercontent.com/chrisrzhou/react-globe/main/textures/globe_dark.jpg"
                markers={markers}
                width="100vw"
                options={options}
            />
        </div>
    );
}

问题原因

react-globe 依赖的 three.js 在组件初始化阶段会直接访问window对象,即便添加了"use client",Next.js 在客户端组件的预渲染(SSR/SSG)环节仍可能触发该环境不兼容问题。

解决方案

方法一:动态导入并禁用 SSR

使用 Next.js 的动态导入功能,明确指定组件不在服务端渲染:

"use client";

import dynamic from 'next/dynamic';
import markers from "./markers";
import markerRenderer from "./markerRenderer";

// 动态导入 react-globe 并禁用服务端渲染
const ReactGlobe = dynamic(() => import('react-globe'), { ssr: false });

const options = {
    markerRenderer,
};

export default function App() {
    return (
        <div className="App">
            <ReactGlobe
                height="100vh"
                globeTexture="https://raw.githubusercontent.com/chrisrzhou/react-globe/main/textures/globe_dark.jpg"
                markers={markers}
                width="100vw"
                options={options}
            />
        </div>
    );
}

方法二:客户端环境判断后渲染

通过条件渲染,确保仅在客户端环境(window存在)时渲染组件:

"use client";

import { useEffect, useState } from 'react';
import ReactGlobe from "react-globe";
import markers from "./markers";
import markerRenderer from "./markerRenderer";

const options = {
    markerRenderer,
};

export default function App() {
    const [isClient, setIsClient] = useState(false);

    useEffect(() => {
        // 组件挂载后确认处于客户端环境
        setIsClient(true);
    }, []);

    // 非客户端环境返回空或加载占位符
    if (!isClient) return null;

    return (
        <div className="App">
            <ReactGlobe
                height="100vh"
                globeTexture="https://raw.githubusercontent.com/chrisrzhou/react-globe/main/textures/globe_dark.jpg"
                markers={markers}
                width="100vw"
                options={options}
            />
        </div>
    );
}

额外注意事项

  • 若markers或markerRenderer文件中存在直接访问window的代码,需同样添加客户端环境判断
  • 方法一的动态导入是更推荐的方案,能从根源避免服务端渲染的环境冲突

内容的提问来源于stack exchange,提问作者Stautenberg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 22:55:17