使用react-leaflet将层绑定到功能组件中的onEachFeature

Bind layer to onEachFeature in functional component with react-leaflet

在渲染 react-leaflet 地图时,我在将 onEachFeature 的上下文绑定到处理程序时遇到了一些麻烦。

这是相关的处理程序

function handleInteractive(
  feature: any,
  layer: L.Layer,
  params: AdditionalBindingParams,
) {
  const { space, store } = params;
  layer.bindTooltip(space.name, {
    permanent: true,
    direction: 'center',
  });

  const onClick = () => {
    const activeSpaceId = getSpaceLayerId(feature);
    const centerFn = this.getBounds; //also tried layer.getBounds
    const coordinates = centerFn ? centerFn().getCenter() : undefined;
    if (store) {
      store.dispatch(setActiveMapLocation({ activeSpaceId, coordinates }));
    }
  };
  layer.on('click', onClick, layer);
}

当我使用断点时,最后一行 layer.on('click', onClick, layer); 绑定 this 正确,但在代码中调用时仍然失败。

如您所见,局部范围内的 this 绑定到目标层 NewClass。还应注意其他层处理程序已正确绑定(例如 bindTooltip)。

也就是说,函数中的传入参数 layer 是未定义的。此外,在 leaflet 内部调用时,定义了 getBounds,但 thisundefined

组件的渲染方式(功能组件,不是 class 组件)

 <GeoJSON
    key={document_id}
    onEachFeature={onEachFeature} /// also tried with `.bind(this)`
    data={...props} />

那里有类似的 SO 问题(例如 ),但我还没有找到解决方案。

我的直觉是底层库中某处有一个箭头函数正在吞噬上下文,但我想我会看看是否有人可以提供帮助。谢谢。

您可以采取一些不同的路线并避免 this,如果您正在转向 React Hooks,这也可能是有益的。

选项 1

通过传单传递额外参数 via .on event:

function handleEachFeature(feature, layer) {
    layer.on("click", (e) => {
      handleClick(e, layer);
    });
}

function handleClick(event, layer) {
  const bounds = layer.getBounds();
  console.log(bounds);
}

选项 2

通过 leaflet L.bind 函数传递额外参数:

function handleEachFeature(feature, layer) {
    layer.on("click", L.bind(handleClick, null, layer));
}

function handleClick(layer) {
  const bounds = layer.getBounds();
  console.log(bounds);
}

选项 3

通过Event.target property获取layer:

function handleEachFeature(feature, layer) {
    layer.on("click", handleClick);
}

function handleClick(event) {
    const bounds = event.target.getBounds();
    console.log(bounds);
}

Note: leaflet package needs to be imported: import * as L from "leaflet";