rolo
rolo

Reputation: 543

How to pass values to components using dynamic import of NextJS

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

Answers (1)

juliomalves
juliomalves

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

Related Questions