尝试让Leaflet JS在Next JS中工作,得到一个元素类型无效的错误。这是动态导入我的Map组件的地方。
/components/MapDir/index.js
import dynamic from 'next/dynamic';
const NewMap = dynamic(() => import('./Map'), {
ssr: false
})
export default NewMap;
/components/MapDir/Map.js
下面是实际的Map组件本身。
import { useEffect } from 'react';
import * as ReactLeaflet from 'react-leaflet';
import 'leaflet/dist/leaflet.css';
import styles from './map.module.css';
import iconMarker2x from 'leaflet/dist/images/marker-icon-2x.png';
import iconMarker from 'leaflet/dist/images/marker-icon.png';
import iconMarkerShadow from 'leaflet/dist/images/marker-shadow.png';
const { MapConsumer, MapContainer } = ReactLeaflet;
const position = [51.505, -0.09]
const Map = ({ children, className, ...rest }) => {
let mapClassName = styles.map;
if ( className ) {
mapClassName = `${mapClassName} ${className}`;
}
useEffect(() => {
delete L.Icon.Default.prototype._getIconUrl
L.Icon.Default.mergeOptions({
iconRetinaUrl: iconMarker2x.src,
iconUrl: iconMarker.src,
shadowUrl: iconMarkerShadow.src
})
}, []);
return (
<MapContainer className={mapClassName} {...rest}>
<MapConsumer>
{(map) => children(ReactLeaflet, map) }
</MapConsumer>
</MapContainer>
)
}
export default Map;
/pages/stores.js
下面是显示Map组件的页面。
import { useState, useEffect } from 'react';
import Head from 'next/head'
import {
ApolloClient,
InMemoryCache,
gql
} from "@apollo/client";
import center from '@turf/center';
import { points } from '@turf/helpers';
import Layout from "@/components/layout";
import {NewMap} from '@/components/MapDir';
import styles from "@/styles/Mapstyles.module.css"
export default function Stores({ storeLocations }) {
const [activeStore, setActiveStore] = useState();
const features = points(storeLocations.map(({ location }) => {
return [location.latitude, location.longitude]
}));
const [defaultLatitude, defaultLongitude] = center(features)?.geometry.coordinates;
return (
<Layout>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
</Head>
<h1>Locations</h1>
<div className={styles.stores}>
<div className={styles.storesLocations}>
<ul className={styles.locations}>
{storeLocations.map(location => {
function handleOnClick() {
setActiveStore(location.id);
}
return (
<li key={location.id}>
<p className={styles.locationName}>
{ location.name }
</p>
<address>
{ location.address }
</address>
<p>
{ location.phoneNumber }
</p>
<p className={styles.locationDiscovery}>
<button onClick={handleOnClick}>
View on Map
</button>
<a href={`https://www.google.com/maps/dir//${location.location.latitude},${location.location.longitude}/@${location.location.latitude},${location.location.longitude},12z/`} target="_blank" rel="noreferrer">
Get Directions
</a>
</p>
</li>
)
})}
</ul>
</div>
<div className={styles.storesMap}>
<div className={styles.storesMapContainer}>
<NewMap className={styles.map} center={[defaultLatitude, defaultLongitude]} zoom={4} scrollWheelZoom={false}>
{({ TileLayer, Marker, Popup }, map) => {
const MapEffect = () => {
useEffect(() => {
if ( !activeStore ) return;
const { location } = storeLocations.find(({ id }) => id === activeStore);
map.setView([location.latitude, location.longitude], 14)
}, [activeStore])
return null;
}
return (
<>
<MapEffect />
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{storeLocations.map(location => {
const { latitude, longitude } = location.location;
return (
<Marker key={location.id} position={[latitude, longitude]}>
<Popup>
<p>{ location.name }</p>
<p>{ location.address }</p>
</Popup>
</Marker>
)
})}
</>
)
}}
</NewMap>
</div>
</div>
</div>
</Layout>
)
}
export async function getStaticProps() {
const client = new ApolloClient({
uri: 'https://api-us-east-1.graphcms.com/v2/ckzvrda212z1d01za7m8y55rc/master',
cache: new InMemoryCache()
});
const data = await client.query({
query: gql`
query PageStores {
storeLocations {
address
id
name
phoneNumber
location {
latitude
longitude
}
}
}
`
})
const storeLocations = data.data.storeLocations;
return {
props: {
storeLocations
}
}
}
1条答案
按热度按时间nfeuvbwi1#
我认为这个错误是因为你在
/components/MapDir/index.js
中做了一个默认的导入,但是你没有调用默认的导入,而是调用了一个上下文中不存在的命名导入。您需要导入这样的组件import NewMap from '@/components/MapDir';
,不带括号。