首页 > 解决方案 > 在 react-leaflet 上通过 useRef 数组移动几个标记

问题描述

我正在尝试react-leaflet根据可拖动标记的位置更改地图上几个标记的位置。
这应该是在拖动可拖动标记时,更改它state会太慢,所以我选择对useRef一组 refs 执行此操作。
问题是r.leafletElement.setLatLng([lat, lng])线被压碎了,因为leafletElementis undefined
(在其他尝试中,我只使用了一个标记而不是一个数组并且useRef工作正常。)
您的帮助将不胜感激,谢谢。

https://codepen.io/erangeva/pen/XWdyZzw

const { Map: LeafletMap, TileLayer, Marker, Popup, CircleMarker } = ReactLeaflet

const Simple = ({ nums }) => {
    const refs = React.useRef([]);
    if (refs.current.length !== nums.length) {
        refs.current = nums.map((_, i) => refs.current[i] || React.createRef());
    }
    return (
        <LeafletMap center={[51.505, -0.09]} zoom={13}>
            <TileLayer
                attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
                url='https://{s}.tile.osm.org/{z}/{x}/{y}.png'
            />
            <Marker position={[51.505, -0.09]} draggable={true}
                ondrag={(e) => {
                    refs.current.map((r, i) => {
                        const lat = e.target.getLatLng().lat;
                        const lng = e.target.getLatLng().lng + 0.01 * i;
                        r.leafletElement.setLatLng([lat, lng]);
                    })
                }}
            >
            </Marker>
            {
                nums.map(i =>
                    <Marker position={[51.505, -0.08 + 0.01 * i]}
                        ref={refs.current[i]}
                    >
                    </Marker>)
            }
        </LeafletMap>
    );

}


ReactDOM.render(<Simple nums={[0, 1, 2, 3, 4]} />, document.getElementById('container'))

标签: javascriptreactjsleafletreact-hooksreact-leaflet

解决方案


在您的示例中,refs初始化方式的方式如下:

{
   current: [
       {current: Marker},
       ... 
   ]
} 

意味着底层标记对象需要像这样处理:

r.current.leafletElement.setLatLng([lat, lng]); 

这就是首先出现提供的错误的原因。


Refs下面演示了另一种无需求助即可操作标记列表的选项:

const MyMarkerList = ({ startPos }) => {

  const [positions, setPositions] = useState(calcPositions(startPos,4));
  
  function handleDrag(e) {
    const latLng = e.target.getLatLng();
    setPositions(calcPositions([latLng.lat, latLng.lng],4));
  }


  return (
    <>
    <Marker
        position={startPos}
        draggable={true}
        ondrag={(e) => {
          handleDrag(e);
        }}
      ></Marker>
      {positions.map((pos, i) => (
        <Marker key={i} position={pos}></Marker>
      ))}
    </>
  );
};

在哪里

function calcPositions(startPos,numOfPos){
  return [...Array(numOfPos)].map((v,i) => {
    return [startPos[0], startPos[1] + 0.01 * (i + 1)];
  });
}

用法

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

推荐阅读