React/Leaflet-side-by-side Error: Map container is already initialized. #35

React/Leaflet-side-by-side Error: Map container is already initialized. #35

我在使用 useEffect 重新渲染地图时遇到问题

  const [baseViewCoords, setBaseViewCoords] = useState([37.715, 44.8611]);

  const searchApiHandler = () => {
  // some code that will fetch new values for baseViewCoords and set to the state
  };

  useEffect(() => {

    var map = L.map('map').setView(baseViewCoords, 13);
    [](url)
    var osmLayer = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap<\/a> contributors'
    }).addTo(map);

    var stamenLayer = L.tileLayer('https://stamen-tiles- 
    {s}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.png', {
        attribution:
            'Map tiles by <a href="http://stamen.com">Stamen Design<\/a>, ' +
            '<a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0<\/a> &mdash; ' +
            'Map data {attribution.OpenStreetMap}',
        minZoom: 1,
        maxZoom: 16
    }).addTo(map)

    L.control.sideBySide(stamenLayer, osmLayer).addTo(map);
  }, [baseViewCoords]);

return (
     <div id="map" />
)

我正在尝试更改地图的位置并在获取 api 后重新渲染它,但在附件中显示 enter image description here

发生这种情况是因为在装载时,L.map 正在寻找 <div id="map" /> 并将其初始化为地图。然后,每当您的 useEffect 运行 时,它都会尝试使用相同的 div 到 运行 L.map 再次 ,但是传单认识到 div 已经是传单地图,所以它出错了。

我建议使用实际的 react-leafet 组件:

import { MapContainer, TileLayer } from 'react-leaflet';

const MyComponent = () => {

  const [baseViewCoords, setBaseViewCoords] = useState([37.715, 44.8611]);
  const [map, setMap] = useState();

  const searchApiHandler = () => {...};

  useEffect(() => {
    if (map){
      L.control.sideBySide(stamenLayer, osmLayer).addTo(map);
    }
  }, [map])

  useEffect(() => {
    if (map){
      map.setView(baseViewCoords)
    }
  }, [map, baseViewCoords]);

  return (
     <MapContainer
       center={baseViewCoords}
       zoom={13}
       whenCreated={map => setMap(map)}
     >
       <TileLayer 
         url={osm_url}
       />
       <TileLayer 
         url={stamen_url}
       />
     </MapContainer>
  )

}