将功能提取到react-leaflet

时间:2020-04-10 16:44:01

标签: leaflet react-leaflet

我的主要目标是在初始加载时在FeatureGroup中渲染react-leaflet时调用fitBounds。

这可以正确呈现-

<Map>
  <LayersControl>
    {getLayers(groups)}
  </LayersControl>
</Map>


function getLayers(featureGroups: MyFeatureGroup[]){
  const showOnLoad = true;
  return featureGroups.map((group: MyFeatureGroup) => {
    const groupRef = createRef<FeatureGroup>();
    const { id, name, } = group;
    return (
      <LayersControl.Overlay checked={showOnLoad} key={id} name={name}>
        <FeatureGroup ref={groupRef}>
          <Layer {...group} />
        </FeatureGroup>
      </LayersControl.Overlay>
    );
  });
}

但是,因为它使用的是函数而不是React组件,所以我无权使用React钩子。

我尝试过的替代方法不起作用,即使它与React组件中包装的相同代码-

...same as above...

  return featureGroups.map((group: MyFeatureGroup) => (
    <ControlledGroup {...group} showOnLoad={showOnLoad} /> ///----- > ADDED THIS HERE
  ));


const ControlledGroup: React.FC<ControlledGroupProps> = (props) => {
  const groupRef = createRef<FeatureGroup>();
  const { map } = useLeaflet();
  /// -----> map is correctly defined here - injecting to all of the layers (LayersControl, FeatureGroup) does not solve the problem 
  const { showOnLoad, ...group } = props;
  useEffect(() => fitBounds(map, groupRef));  ///-----> Primary Goal of what I am trying to accomplish
  return (
    <LayersControl.Overlay
      checked={showOnLoad}
      key={group.id}
      name={name}
    >
      <FeatureGroup ref={groupRef}>
        <Layer map={map} {...group} />
      </FeatureGroup>
    </LayersControl.Overlay>
  );
};

我有点困惑,因为这是相同的代码。在两种情况下,getLayers函数均返回ReactNode。但是,当移至独立的ControlledGroup组件时,它将在渲染上引发错误-

addOverlay is not a function

我尝试为react-leaflet创建一个自定义类组件,但是遇到的困难是createLeafletElement返回一个Leaflet.Element,而我只是想返回一个{{1} }。也就是说,所有这些都已经是有效的ReactNode组件。

我的问题-为什么一个有效,而另一个无效?将函数转换为可渲染的独立React组件的正确/推荐方法是什么?

此外,如果还有替代模式可以调用fitBounds,那么这也将有所帮助。

任何见识将不胜感激。

1 个答案:

答案 0 :(得分:0)

由于LayersLayers.Overlay共享继承,因此呈现错误的解决方案是将图层保持在一起并将要素组移动到独立组件。

这可以按预期工作,并允许我在groupRef上致电useEffect-

function getLayers(groups: MyFeatureGroup[]){
  return featureGroups.map((group: MyFeatureGroup) => {
    const { id, name, } = group;
   return (
///---> Keep the Overlay in the function here and extract just the FeatureGroup out
      <LayersControl.Overlay checked={showOnLoad} key={id} name={name}> 
        <ControlledGroup {...group}></ControlledGroup>
       </LayersControl.Overlay>
    );
}