无法将 Leaflet 与 NextJS 一起使用

wat*_*902 0 leaflet typescript reactjs next.js

我想用Leaflet我想与 NextJS(typescript) 一起

但Leaflet不支持SSR。所以,我用react-leaflet-univarsal.

然后,我自定义了Leaflet的Marker组件。所以,我想用Leaflet.Icon. 我尝试了两件事。

  1. if(process.browser){}

这是没有找到的window

  1. 使用动态导入next/dynamic
let iconPerson: any;
  const DynamicComponent = dynamic(
    () =>
      import('leaflet').then(L => {
        iconPerson = (L as any).Icon.extend({
          options: {
            iconUrl: '/images/icon1.jpg',
            iconRetinaUrl: '/images/icon1.jpg',
            iconSize: new (L as any).Point(60, 75),
            className: 'leaflet-div-icon',
          },
        });
      }) as any,
    { ssr: false },
  );

....

<Marker icon={iconPerson}>

Run Code Online (Sandbox Code Playgroud)

这是打印出来的。> 无法读取未定义的属性“createIcon”

L.icon是和NextJS一起使用的方式吗?

wat*_*902 5

我通过SSR Map组件解决了这个问题。

尤其,

import * as React from 'react';
import { Map as M, TileLayer, Marker, Popup } from 'react-leaflet-universal';
import L from 'leaflet';
import { Pois } from '../types/pois';

const iconPerson = new L.Icon({
  iconUrl: '/images/icon1.svg',
  iconRetinaUrl: '/images/icon1.svg',
  iconAnchor: [20, 40],
  popupAnchor: [0, -35],
  iconSize: [40, 40],
});

const MAXIMUM_ZOOM = 18;

type Props = {
  position: { lat: number; lng: number };
  pois: Pois[];
};

const Map: React.FC<Props> = ({ position, pois }) => (
  <M center={position} zoom={MAXIMUM_ZOOM} doubleClickZoom={false}>
    <TileLayer
      attribution='copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
      url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
    />
    <Marker position={position} />
    {pois.map((poi: any) => (
      <Marker position={{ lat: poi.geo.x, lng: poi.geo.y }} icon={iconPerson} key={poi.id}>
        <Popup>{poi.description}</Popup>
      </Marker>
    ))}
  </M>
);

export default Map;

Run Code Online (Sandbox Code Playgroud)

const Map: any = dynamic(() => import('./Map') as any, { ssr: false });

return <Map ... />
Run Code Online (Sandbox Code Playgroud)

谢谢。