NextJS13中使用react-leaflet报错的问题求助
在Next.js 13中解决Leaflet地图的客户端渲染问题
你遇到的核心问题是同时混用"use client"指令和next/dynamic的ssr: false配置导致的组件加载冲突,另外单独使用"use client"时,react-leaflet在服务端预渲染阶段会直接访问window对象引发错误。以下是两种可行的解决方案:
方案一:客户端组件+动态导入Leaflet依赖
保留组件的"use client"标记,通过useEffect延迟加载react-leaflet,确保仅在客户端环境执行依赖window的代码:
修改LeafletMap组件
"use client" import React, { useEffect, useState } from 'react'; const LeafletMap = () => { const [MapContainer, setMapContainer] = useState(null); const [TileLayer, setTileLayer] = useState(null); useEffect(() => { // 仅在客户端动态导入react-leaflet const loadLeaflet = async () => { const { MapContainer, TileLayer } = await import('react-leaflet'); setMapContainer(MapContainer); setTileLayer(TileLayer); }; loadLeaflet(); }, []); if (!MapContainer) return <div>加载地图中...</div>; // 注意给MapContainer设置宽高,否则地图不会显示 return ( <MapContainer center={[51.505, -0.09]} zoom={13} scrollWheelZoom={false} style={{ height: '400px', width: '100%' }} > <TileLayer attribution='© OpenStreetMap contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" /> </MapContainer> ); }; export default LeafletMap;
修改页面组件
直接导入组件即可,无需dynamic和Suspense:
import styles from './page.module.css'; import LeafletMap from './(components)/LeafletMap/LeafletMap'; export default function Home() { return ( <div className={styles.container}> <h1>Collab Mapping</h1> <LeafletMap /> </div> ); }
方案二:仅使用next/dynamic(移除"use client")
完全依赖next/dynamic的ssr: false配置,确保组件仅在客户端渲染:
修改LeafletMap组件
移除"use client"标记:
import React from 'react'; import { MapContainer, TileLayer } from 'react-leaflet'; const LeafletMap = () => { return ( <MapContainer center={[51.505, -0.09]} zoom={13} scrollWheelZoom={false} style={{ height: '400px', width: '100%' }} > <TileLayer attribution='© OpenStreetMap contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" /> </MapContainer> ); }; export default LeafletMap;
修改页面组件
用dynamic导入并配置ssr: false,无需Suspense:
import styles from './page.module.css'; import dynamic from 'next/dynamic'; const Map = dynamic(() => import('./(components)/LeafletMap/LeafletMap'), { ssr: false, loading: () => <div>加载地图中...</div> }); export default function Home() { return ( <div className={styles.container}> <h1>Collab Mapping</h1> <Map /> </div> ); }
错误原因解析
- 混用"use client"和dynamic ssr: false:客户端组件本身已标记为客户端渲染,再叠加
ssr: false会导致组件导出被错误处理,触发object is not a function异常。 - 单独用"use client"出现window undefined:react-leaflet在导入阶段就会执行Leaflet核心代码,而Next.js客户端组件仍会在服务端做预渲染(生成静态HTML),此时
window对象不存在,引发报错。
内容的提问来源于stack exchange,提问作者a.urbanite
相关产品推荐
相关产品推荐

