Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React leaflet center attribute does not change when the center state changes

App.js

import { useState } from 'react';

const App = () => {
  // This state is used to the center attribute of MapContainer component
  const [mapCenter, setMapCenter] = useState([34.80746, -40.4796]);
  // This state is used to the zoom attribute of MapContainer component
  const [mapZoom, setMapZoom] = useState(3);

  const onClickHandler = () => {
    setMapCenter([20, 100]);
    setMapZoom(5);
  };

  return (
    <>
      <button onClick={onClickHandler}>Change map's center location</button>
      <Map center={mapCenter} zoom={mapZoom} />
    </>
  );
};

Map.js

import React from 'react';
import './Map.css';
import { MapContainer, TileLayer } from 'react-leaflet';

function Map({ center, zoom }) {
  return (
    <div className="map">
      <MapContainer center={center} zoom={zoom}>
        <TileLayer
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          attribution='&copy; <a 
                href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        />
      </MapContainer>
    </div>
  );
}

export default Map;

Map.css

.map {
  height: 500px;
  background-color: white;
  padding: 1rem;
  border-radius: 20px;
  margin-top: 16px;
  box-shadow: 0 0 8px -4px rgba(0, 0, 0, 0.5);
}

.map .leaflet-container {
  height: 100%;
}

When I clicks button, mapCenter state clearly changes to [20, 100] and mapZoom also changes to 5. But in the Map Component Map does not show new center. but I don't know why. I already checked state's change. Map never respond. Does anyone knows??? Please answer a way to figure it out.

like image 254
박병찬 Avatar asked Nov 03 '20 15:11

박병찬


1 Answers

Except for its children, MapContainer props are immutable: changing them after they have been set a first time will have no effect on the Map instance or its container. The Leaflet Map instance created by the MapContainer element can be accessed by child components using one of the provided hooks or the MapConsumer component.
https://react-leaflet.js.org/docs/api-map

ChangeView.js

function ChangeView({ center, zoom }) {
  const map = useMap();
  map.setView(center, zoom);
  return null;
}

Map.js

function Map({ center, zoom }) {
  return (
    <div className="map">
      <MapContainer center={center} zoom={zoom} scrollWheelZoom={false}>
        <ChangeView center={center} zoom={zoom} /> 
        <TileLayer
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        />
      </MapContainer>
    </div>
  );
}

The react-leaflet documentation uses setCenter in it's useMapEvent example, but this function isn't defined. However in leaflets documentation Methods for modifying map state there is a function setView(center, zoom, options?).

like image 180
0xnoob Avatar answered Oct 08 '22 19:10

0xnoob