如何在Next.js中传递getStaticProps结果至Leaflet Canvas图层
问题原因及解决步骤
核心问题
getStaticProps仅支持页面组件:你把它放在了普通组件LeafletCanvasMarker中,Next.js不会执行非页面组件内的数据获取方法,导致props始终为undefined。- 数据传递链路断裂:页面组件未获取数据,也没有将数据逐层传递给子组件。
- Fetch路径错误:
.api/getpoints缺少开头斜杠,正确路径应为/api/getpoints。 - getStaticProps返回值错误:你声明了变量
data,但返回时使用了未定义的features,需从data中提取实际需要的features数组。
具体修改步骤
1. 迁移getStaticProps到页面组件
修改mapPage页面组件,添加数据获取逻辑并传递给地图组件:
import Head from 'next/head' import dynamic from 'next/dynamic'; const MapWithNoSSR = dynamic(() => import("../components/Map"), { ssr: false }); const mapPage = ({ features }) => { return ( <div> <Head> <title>About</title> </Head> <h1>Map of Peng spots</h1> <p>Map should go here!</p> {/* 传递features给地图组件 */} <MapWithNoSSR features={features} /> </div> ) } // 仅页面组件可使用getStaticProps export async function getStaticProps() { // 修正fetch路径 const data = await fetch('/api/getpoints').then(r => r.json()) // 提取GeoJSON中的features数组 const features = data.features || [] return { props: { features } } } export default mapPage
2. 修改Map组件,接收并传递props
让Map组件接收features,再传递给子组件LeafletCanvasMarker:
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet' import 'leaflet/dist/leaflet.css' import 'leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css' import 'leaflet-defaulticon-compatibility'; import LeafletCanvasMarker from './Pengs'; // 接收features参数 const Map = ({ features }) => { return ( <MapContainer center={[50.1109, 8.6821]} zoom={14} scrollWheelZoom={false} style={{height: "100vh", width: "100%"}}> <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" attribution="© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors" /> <Marker position={[50.1109, 8.682]} draggable={true} animate={true} > </Marker> {/* 传递features给Canvas图层组件 */} <LeafletCanvasMarker features={features} /> </MapContainer> ) } export default Map
3. 修正LeafletCanvasMarker组件
移除无效的getStaticProps,并完善数据监听逻辑:
import { useEffect } from "react"; import { useMap } from "react-leaflet"; import "leaflet-canvas-marker"; import L from "leaflet"; export default function LeafletCanvasMarker({features}) { console.log({features}) const map = useMap(); useEffect(() => { // 增加数据为空时的判断 if (!map || !features?.length) return; const ciLayer = L.canvasIconLayer({}).addTo(map); ciLayer.addOnClickListener(function (e, data) { console.log(data); }); ciLayer.addOnHoverListener(function (e, data) { console.log(data[0].data._leaflet_id); }); const icon = L.icon({ iconUrl: "https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon.png", iconSize: [20, 18], iconAnchor: [10, 9], }); // 传入features数组(若leaflet-canvas-marker要求包裹为对象,可改为{features}) ciLayer.addLayers(features); }, [map, features]); // 添加features到依赖,数据更新时重新渲染 return null; } // 移除此处的getStaticProps,普通组件不支持该方法
额外说明
- 你使用的
dynamic import并设置ssr: false会让地图组件在客户端渲染,但页面组件的getStaticProps仍会在构建时执行,提前获取数据并传递给客户端组件。 - 若需要数据实时更新,可改用
getServerSideProps或在LeafletCanvasMarker组件内通过useEffect直接发起请求,但静态生成场景下getStaticProps性能更优。
内容的提问来源于stack exchange,提问作者nizz0k
相关产品推荐
相关产品推荐

