首页 > 解决方案 > 如何在反应传单中打开弹出窗口?

问题描述

我正在开发一个具有多个标记的反应传单地图。我的目的是让弹出窗口一个一个地打开。

所以,我的标记是通过映射一个数组并返回组件来呈现的

arr.map((item, i) => <CustomMarker isActive={isActive} data={item} key={i} />)

isActive是一个值,表示弹出窗口应该处于活动状态。

<CustomMarker />看起来像这样:

const CustomMarker = ({isActive, data}) => {
  return (
    <Marker position={data.position}>
      <Popup>
        <a href={data.url}>Go to this website</a>
      </Popup>
    </Marker>
  )
}

我尝试了几件事,但没有一个对我有用。

  1. 通过实施eventHandlers
  2. 使用自定义弹出窗口创建自定义图标L.divIcon()并编写 HTML。但是,弹出窗口是不可点击的,因为它是标记图标的一部分。

如何使用isActive值打开弹出窗口?

标签: javascriptleafletreact-leaflet

解决方案


您可以通过获取 react-leafletPopup组件的 ref 来做到这一点,一旦该 ref 准备好,使用它来调用openOnL.popup 的方法。

首先,您需要一个可以传递给每个 CustomMarker 的地图参考:

const Map = (props) => {
  const [map, setMap] = useState();

  return (
    <MapContainer
      whenCreated={setMap}
      {...otherProps}
    >
      <CustomMarker
        map={map}
        data={{
          position: [20.27, -157]
        }}
      />
      <CustomMarker
        map={map}
        data={{
          position: [20.27, -156]
        }}
        isActive
      />
    </MapContainer>
  );
};

如您所见,每个 CustomMarker 都将地图引用作为道具。然后在 CustomMarker 中,您需要获取Popup组件的引用。请注意,安装时将不提供 ref。您需要等待 ref 可用。但是因为 useEffect 不会在 ref 更改值时导致重新渲染,所以您可以通过在 ref 回调中设置状态变量来让组件知道 ref 已准备好:

const CustomMarker = ({ isActive, data, map }) => {
  const [refReady, setRefReady] = useState(false);
  let popupRef = useRef();

  useEffect(() => {
    if (refReady && isActive) {
      popupRef.openOn(map);
    }
  }, [isActive, refReady, map]);

  return (
    <Marker position={data.position}>
      <Popup
        ref={(r) => {
          popupRef = r;
          setRefReady(true);
        }}
      >
        Yupperz
      </Popup>
    </Marker>
  );
};

ref 仅在组件安装后可用。在refprop 中,首先我们将 ref 设置为我们的useRef值,然后我们将 state 变量更改refReady为 true。当这个值改变时,useEffect 触发。if 语句确保 ref 确实存在。如果 ref 已准备好并且isActive为 true,我们调用 L.popup.openOn(map),并且您的弹出窗口在挂载时打开。

工作代码框

或者,如果您不想打扰所有这些,这些功能(以及更多!)内置于react-leaflet-editable-popup中。


推荐阅读