Next.js 13使用React-Leaflet:解决Window未定义后遇Hydration失败问题
解决Next.js 13中React-Leaflet的Hydration错误
问题根源
动态导入关闭SSR后,服务端会渲染空内容,而客户端渲染地图组件,导致初始UI与服务端输出不匹配,触发Hydration失败错误。
解决方案
通过客户端状态控制渲染时机+统一服务端/客户端初始占位来解决,具体修改如下:
1. 优化地图组件(CoordinateMap.tsx)
"use client" import { useEffect, useState } from 'react'; import { MapContainer, TileLayer } from 'react-leaflet'; import "leaflet/dist/leaflet.css"; interface Props { height: string width: string coordinateList?: any } export default function CoordinateMap({ height, width }: Props ): JSX.Element { const [isClient, setIsClient] = useState(false); useEffect(() => { // 组件在客户端挂载后才标记为可渲染地图 setIsClient(true); }, []); // 服务端/客户端初始渲染时返回统一的占位容器 if (!isClient) { return <div style={{ height, width }} />; } return ( <MapContainer dragging={false} style={{ height, width }} scrollWheelZoom={false} zoomControl={false} center={[28.3949, 84.1240]} doubleClickZoom={false} zoom={7} > <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" attribution="© OpenStreetMap contributors" /> </MapContainer> ); };
2. 简化动态导入代码(Map.tsx)
import dynamic from "next/dynamic"; const CoordinateMap = dynamic(() => import('@/app/_components/GlobalMap/CoordinateMap'), { ssr: false, // 可选:添加加载占位提升体验 loading: () => <div style={{ height: '100%', width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>加载地图中...</div> }); export default CoordinateMap;
关键说明
- 通过
useState和useEffect确保MapContainer仅在客户端环境渲染,服务端返回与客户端初始状态一致的空容器,避免Hydration不匹配。 - 动态导入时的
loading占位可选,但能提升用户等待体验,同时保证服务端与客户端的初始DOM结构一致。 - 移除未使用的导入(如
useMap、GeoJSON等),减少冗余代码。
内容的提问来源于stack exchange,提问作者Aakash Bandhu Aryal
相关产品推荐
相关产品推荐

