React Leaflet - 更新地图中心

React Leaflet - Update map center

我正在使用 React Leaflet。我有一张地图和一个带有名称和相应位置的数组。数组中的每个名称都是一个按钮。当我点击一个名字时,位置会发生变化,并且应该在地图中更新。这适用于标记,但不适用于地图的部分。我怎样才能同时更新地图的部分?

const data = [
      {
        name: 'John',
        coordinates: {
          langitude: '40.72260370101827',
          latitude: '-73.99323791583221',
        },
      },
      {
        name: 'Bob',
        coordinates: {
          langitude: '40.72843542344666',
          latitude: '-73.94860440141105',
        },
      },
      {
        name: 'Chris',
        coordinates: {
          langitude: '40.79159996340942',
          latitude: '-73.94077957876242',
        },
      },
    ];

export default function Map(props) {
  const { index, data } = props;

  return (
    <MapContainer
      center={[
        data[index].coordinates.langitude,
        data[index].coordinates.latitude,
      ]}
      zoom={16}
    >
      <TileLayer
        attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      ></TileLayer>
      <Marker
        position={[
          data[index].coordinates.langitude,
          data[index].coordinates.latitude,
        ]}
      >
        <Popup>{data[index].name}</Popup>
      </Marker>
    </MapContainer>
  );
}

来自官方docs:

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.

因此,您必须创建一个自定义组件,在坐标更改时更改地图视图

function SetViewOnClick({ coords }) {
  const map = useMap();
  map.setView(coords, map.getZoom());

  return null;
}

通过将坐标作为道具传递,将其作为 MapContainer 的子项使用在标记组件下方。

<SetViewOnClick
        coords={[
          data[index].coordinates.langitude,
          data[index].coordinates.latitude
        ]}
/>

收到更新后的索引后,地图的视图将发生变化。

Demo

以下是此问题的完整说明:another thread。基本上 MapContainercenter 道具(以及所有其他道具,子级除外)是不可变的,因此您需要使用上面答案中解释的提供的方法。
但是,这里有一个我想到的快速修复:

 <MapContainer
     key={JSON.stringify([data[index].coordinates.langitude, data[index].coordinates.latitude])}
     center={[
        data[index].coordinates.langitude,
        data[index].coordinates.latitude,
     ]}
     zoom={16}
>

唯一添加到您的代码的是 key 道具,它占据了字符串化的中心位置。因此,当位置发生变化时,将创建 MapContainer 组件的另一个实例(一个新副本 ;)),具有正确的 center 值。