Search code examples
reactjsnext.jsreact-leaflet

get a state from another component


I have a Map component with a state.

const [userPickPos, setUserPickPos] = useState() 

This state represents a marker's position on a map.

This Map component is returned in a page component. On this page I want to access this marker's position(the state of it) from the Map component. How can I do that?

Map:

const Map = (userPos) => {

  const [userPickPos, setUserPickPos] = useState() 
  const MapEvents = () => {
    useMapEvents({
      click(e) {
        const lat = e.latlng.lat;
        const lng = e.latlng.lng;

        setUserPickPos({lat: lat,lng: lng})
        console.log(userPickPos)
      },
    });
}


  const bounds = new LatLngBounds([81.505, -0.09], [50.773941, -84.12544])

    return (
    <>
        <Head>
            <link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css"
            integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
            crossorigin=""/>

            <script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"
            integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og=="
            crossorigin=""></script>
        </Head>

        <MapContainer 
        className='absolute h-screen w-[1500px] left-[520px] top-[56px] bg-no-repeat bg-cover bg-[#738aaf]'
        center={[71.505, -40.09]} zoom={3} scrollWheelZoom={true} noWrap={true}>
        <ImageOverlay
          url="/allmaphres.png"
          bounds={bounds}
          opacity={1}
          zIndex={10}
        />
        {userPickPos && 
          <Marker position={userPickPos}>
            <Popup>
              Your Pick.
            </Popup>
          </Marker>
        }
         <MapEvents />
      </MapContainer>
    </>
    );

}

All (page):

const All = () => {
    . // I need to use the state here
    .
    .
    return (
    <Map />
    )
}

Solution

  • Edit:

    State created in Parent Component and sent to Child Component

    Map (Child):

    const Map = ({userPickPos,setUserPickPos}) => {
    
      const MapEvents = () => {
        useMapEvents({
          click(e) {
            const lat = e.latlng.lat;
            const lng = e.latlng.lng;
    
            setUserPickPos({lat: lat,lng: lng});
            console.log(userPickPos)
          },
        });
    }
    

    All page (Parent)

    import React from 'react';
    const All = () => {
    
      const [userPickPos, setUserPickPos] = useState()
      
    
    
     return <Map userPickPos={userPickPos} setUserPickPos={setUserPickPos} />
    }
    
    export default All;
    

    State created in Child Component and used in Parent Component

    Map (Child):

    const Map = ({handleCallBack}) => {
    
      const [userPickPos, setUserPickPos] = useState() 
      const MapEvents = () => {
        useMapEvents({
          click(e) {
            const lat = e.latlng.lat;
            const lng = e.latlng.lng;
            setUserPickPos({lat: lat,lng: lng})
            props.handleCallBack(userPickPos)
            console.log(userPickPos)
          },
        });
    }
    .
    .
    .
    

    All page (Parent)

    const All = () => {
        
        const handleCallBack = (pos)=>{
            console.log(pos) 
        }
    
        return (
        <Map handleCallBack={handleCallBack}/>
        )
    }
    

    That way you could use the state in both components.