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

如何在Remix.js应用中添加react-leaflet地图并解决window未定义问题

解决Remix中react-leaflet的window is not defined错误

核心原因

react-leaflet依赖Leaflet库,而Leaflet初始化时会直接访问window对象。Remix默认启用服务端渲染(SSR),服务端环境不存在window,因此必须确保地图相关代码仅在客户端执行。


1. 用RemixClientOnly组件+动态导入隔离客户端代码

更新你的LazyMap.tsx,通过ClientOnly确保地图组件只在客户端渲染,同时用动态导入避免服务端加载依赖:

import { ClientOnly } from "@remix-run/react";
import { Suspense } from "react";

export default function LazyMap() {
  return (
    <Suspense fallback={<div>加载地图中...</div>}>
      <ClientOnly>
        {async () => {
          // 仅在客户端动态导入Map组件
          const { default: Map } = await import("./Map");
          return <Map />;
        }}
      </ClientOnly>
    </Suspense>
  );
}

2. 修改Map组件,避免顶层导入Leaflet

将Leaflet和react-leaflet的依赖导入放到组件内部,仅在客户端环境执行:

import { useEffect, useState } from "react";

export default function Map() {
  const [MapComponent, setMapComponent] = useState(null);
  const [TileLayerComponent, setTileLayerComponent] = useState(null);

  useEffect(() => {
    async function loadMapDependencies() {
      // 动态加载Leaflet CSS
      const leafletCss = document.createElement("link");
      leafletCss.rel = "stylesheet";
      leafletCss.href = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.css";
      document.head.appendChild(leafletCss);

      // 客户端环境下加载react-leaflet组件
      const { Map, TileLayer } = await import("react-leaflet");
      setMapComponent(Map);
      setTileLayerComponent(TileLayer);
    }

    loadMapDependencies();
  }, []);

  if (!MapComponent || !TileLayerComponent) {
    return <div>初始化地图...</div>;
  }

  return (
    <div style={{ height: "400px", width: "100%" }}>
      <MapComponent center={[51.505, -0.09]} zoom={13}>
        <TileLayerComponent
          attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />
      </MapComponent>
    </div>
  );
}

3. 确认依赖安装正确

确保已安装所需依赖:

npm install react-leaflet leaflet
# TypeScript用户额外安装类型声明
npm install @types/leaflet --save-dev

关键注意事项

  • 禁止在模块顶层导入react-leaflet或leaflet,模块代码会在服务端执行,直接触发window报错
  • 所有依赖window的逻辑必须放在useEffect或客户端专属执行分支中
  • ClientOnly组件的回调函数仅在客户端渲染阶段执行,能有效隔离服务端代码

内容的提问来源于stack exchange,提问作者jack.benson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 19:32:46