Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 807
rolo Avatar asked Oct 15 '22 22:10

rolo


1 Answers

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} /> 
}

like image 100
juliomalves Avatar answered Oct 20 '22 17:10

juliomalves