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

如何在Next.js中传递getStaticProps结果至Leaflet Canvas图层

问题原因及解决步骤

核心问题

  1. getStaticProps仅支持页面组件:你把它放在了普通组件LeafletCanvasMarker中,Next.js不会执行非页面组件内的数据获取方法,导致props始终为undefined。
  2. 数据传递链路断裂:页面组件未获取数据,也没有将数据逐层传递给子组件。
  3. Fetch路径错误:.api/getpoints缺少开头斜杠,正确路径应为/api/getpoints。
  4. 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="&copy; <a href=&quot;http://osm.org/copyright&quot;>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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 13:45:33