prakash subba
prakash subba

Reputation: 51

how to change the center of the map container react-leaflet?

I want to be able to change the center of the react-leaflet map container by clicking the workout container which is an object that has the co-ordinates. I have shared all the states throughout the components using contextApi

//WorkoutData.js

export const WorkoutsData = [
  {
  id: 1,
  coords: {latitude: 56.27360151291927, 
  longitude:-82.84886256490017},
  },
  
  {
  id: 2,
  coords: {latitude: 49.27360151291927, 
  longitude: -75.84886256490017},
  },

  {
  id: 3,
  coords: {latitude: 39.27360151291927, 
  longitude: -79.84886256490017},
  }
];

//MapLocation.js i have a main.js folder which has all the state variable and all the other components shares the variable using contextapi

    import React, { useEffect, useState } from "react";
    import "./styles.css";
    import { WorkoutsData } from "./WorkoutLocation";

    const MapLocation() => {
const [workouts, setWorkouts] = useState(WorkoutsData);
const [changedCoords, setChangedCoords] = useState({latitude: 0, longitude: 0})
const [workoutsClicked, setWorkoutsClicked] = useState(false);

     
 const locateWorkout = (id) => {
        setWorkoutsClicked(true)
        const findLocation = workouts.find((exercise) => {
          return exercise.id === id;
        });
        
        setChangedCoords({
          latitude: findLocation.coords.latitude,
          longitude: findLocation.coords.longitude
        })
      }



return(
<>
workouts.map((workout) => {
return(
<div key = {workout.id} className = 'workout-info'>
<div className = "workout-details">
<p>{workout.coords}</p>
</div>
</div>
)
})
</>
)
export default MapLocation;

//Map.js i have a main.js folder which has all the state variable and all the other components shares the variable using contextapi

const Map = () => {
const[initialCoords, setInitialCoords] = useState({latitude: 0, longitude: 0})

 useEffect(() => {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition((position) => {
        setInitialCoords({
          latitude: position.coords.latitude,
          longitude: position.coords.longitude
        })
      })
    }
  }, [])



return(
<>
 <MapContainer center = { 
workoutsClicked !== true ? 
[initialCoords.latitude, initialCoords.longitude] : 
[changedCoords.latitude, changedCoords.longitude]}
zoom = {20}>

<TileLayer attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"/>

</MapContainer>
</>
)
}

export default Map

Upvotes: 3

Views: 2306

Answers (1)

Ian A
Ian A

Reputation: 6163

MapContainer props in React Leaflet are immutable (https://react-leaflet.js.org/docs/api-map/#mapcontainer), therefore updating them after the map is initialised will have no effect.

You can use the useMapEvent hook to update the centre of the map when your changedCoords state changes. First of all define a function:

function UpdateMapCentre(props) {
  const map = useMap();
  map.panTo(props.mapCentre);
  return null;
}

Then add the following as a child of MapContainer:

<MapContainer ...>
  ...
  <UpdateMapCentre mapCentre={changedCoords} />
</MapContainer>

Because the props passed to MapContainer are immutable, you no longer need the ternary if statement to set the map centre (updating the map centre is now taken care of using <UpdateMapCentre>) and can just pass in the initialCoords.

<MapContainer center={[initialCoords.latitude, initialCoords.longitude]} zoom={20}>
  ...
</MapContainer>

See this StackBlitz for a working demo. When you click on the latLng of a workout in the list below the map, the changedCoords state will be updated and the map will pan to the latitude and longitude of the workout.

Upvotes: 3

Related Questions