Reputation: 543
I have a problem with dynamic import in Next.js. It would be great if someone could give me an answer or some advice to do this in a different way.
The thing is that I have a component that renders a leaflet-map, this map have a pointer so I could click the map and have longitude and latitude, this is the code:
import React from 'react'
import {MapContainer, Marker,TileLayer, useMapEvents } from 'react-leaflet'
import { iconMap } from '../../assets/customeIcon/iconMap';
import 'leaflet/dist/leaflet.css'
const MapView =({selectedPosition,setSelectedPosition}) =>{
const [initialPosition, setInitialPosition] = React.useState([38,-101]);
const Markers = () => {
const map = useMapEvents({
click(e) {
setSelectedPosition([
e.latlng.lat,
e.latlng.lng
]);
},
})
return (
selectedPosition ?
<Marker
key={selectedPosition[0]}
position={selectedPosition}
interactive={false}
icon={iconMap}
/>
: null
)
}
return <MapContainer center={selectedPosition || initialPosition} zoom={5} style={{height:"300px",width:"540px"}}>
<TileLayer url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
></TileLayer>
<Markers />
</MapContainer>
}
export default MapView
As you can see this component has the parameters selectedPosition
and setSelectedPosition
. This is where I save the clicked position and return it to the parent component.
For example, the parent component used to call the map component this way:
const Parent = () => {
const [selectedPosition, setSelectedPosition] = React.useState(null);
...
<MapView selectedPosition={selectedPosition} setSelectedPosition={setSelectedPosition} > </MapView>
}
This used to work great, but now because of a problem with react-leaflet I have to call the map in a different way, using Next.js dynamic import, I had to create a new component that is like this:
import dynamic from 'next/dynamic';
function MapCaller() {
const Map = React.useMemo(() => dynamic(
() => import('./MapView'),
{ ssr: false, }
), [])
return <Map />
}
export default MapCaller
So now the parent component has to call the MapCaller
instead of directly calling the MapView
:
const Parent = () => {
const [selectedPosition, setSelectedPosition] = React.useState(null);
...
<MapCaller > </MapCaller>
}
With this I resolved the problem of react-leaflet, but I have other problem now, remember that I used to pass the position values to the map component, how could I do to pass that values with this new approach? How the parent component could communicate with the map to get the selected position? Is there another approach to do this?
Thanks!
Upvotes: 14
Views: 13984
Reputation: 50278
Your <MapCaller>
component is simply wrapping the existing <MapView>
, so you could simply pass the props down to it.
const Map = dynamic(() => import('./MapView'), { ssr: false })
function MapCaller({ selectedPosition, setSelectedPosition }) {
return <Map selectedPosition={selectedPosition} setSelectedPosition={setSelectedPosition} />
}
Then use it in the parent component:
const Parent = () => {
const [selectedPosition, setSelectedPosition] = React.useState(null);
//...
<MapCaller selectedPosition={selectedPosition} setSelectedPosition={setSelectedPosition} />
}
Upvotes: 14