Reputation: 452
I am working on developing a react-leaflet map that has multiple markers. My intention is to make popups open one by one with interval.
So, my markers are rendered by mapping an array and returning component
arr.map((item, i) => <CustomMarker isActive={isActive} data={item} key={i} />)
isActive
is a value that says should popup be active.
<CustomMarker />
looks like this:
const CustomMarker = ({isActive, data}) => {
return (
<Marker position={data.position}>
<Popup>
<a href={data.url}>Go to this website</a>
</Popup>
</Marker>
)
}
I tried several things but none do work for me.
eventHandlers
L.divIcon()
and write HTML with custom popup. However, popup was unclickable as it was a part of markers icon.How can use isActive
value to open popup?
Upvotes: 4
Views: 13700
Reputation: 10686
You can do this by getting a ref to the react-leaflet Popup
component, and once that ref is ready, using it to call the openOn
method of an L.popup.
First you need a ref to the map that can be passed to each 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>
);
};
As you can see, each CustomMarker takes the map reference as a prop. Then within the CustomMarker, you need to get a ref to the Popup
component. Note that a ref will not be available on mount. You need to wait for the ref to be available. But because useEffect's dont cause rerenders when a ref changes value, you can let the component know the ref is ready by setting a state variable in a ref callback:
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>
);
};
The ref is only available once the component mounts. In the ref
prop, first we set the ref to our useRef
value, and then we change the state variable refReady
to be true. The useEffect fires when this value changes. The if statement assures that the ref indeed exists. If the ref is ready, and isActive
is true, the we call L.popup.openOn(map), and your popup is open on mount.
Or, if you don't want to bother with all that, ths functionality (and more!) is built in to a react-leaflet-editable-popup.
Upvotes: 6