const IconGen = ({ incomingData }) => {
const [dataMap, setDataMap] = useState({});
const dataMapTemp = {};
incomingData.BandData.forEach((each) => {
dataMapTemp[each.AntennaX].list.push(each);
dataMapTemp[each.AntennaX].angle= each.angle;
dataMapTemp[each.AntennaX].sId = each.SID;
});
if (!dataMap[1]) {
setDataMap(dataMapTemp);
}
return (
<div class="container_Sector" >
<div class="circle" style={{backgroundColor : "#c31605"></div>
<div
id = {dataMap && dataMap[1]?.sId }
style={{
rotate: `${dataMap[1]?.angle}deg`,
}}
onClick={() => {
alert("You clicked the sector!");
}
}
>
{dataMap[1]?.list.map((each) => generateSvg(each))}
</div>
<div
style={{
rotate: `${dataMap[2]?.angle}deg`,
}}
>
{dataMap[2]?.list.map((each) => generateSvg(each))}
</div>
<div
style={{
rotate: `${dataMap[3]?.angle}deg`,
}}
>
{dataMap[3]?.list.map((each) => generateSvg(each))}
</div>
</div>
);
};
export default IconGen;
//Parent Component
<MapContainer>
<Marker
key={data.SiteID}
position={[data.Latitude, data.Longitude]}
icon = <IconGen
incomingData={data}
/>
>
</Marker>
</Mapcontainer>
I am able to render custom icon using icon={L.divIcon({ className: "custom icon", html: ReactDOMServer.renderToString( <MyComponent/> ) })}.
However the onClick within the custom icon component does not trigger. onClick is not working due to rendering the MyComponent using ReactDOMServer.renderToString.
I need the onClick event inside the custom component to function correctly.
I have now published this solution as a library at @adamscybot/react-leaflet-component-marker.
The reason that the
onClickhandler does not work is thatrenderToStringmeans the component isn't truly mounted, in the sense that React is not aware of it as an ongoing concern. RunningrenderToStringreduces the component to whatever the DOM looks like for that component on its first render, and nothing else will change that from the pointrenderToStringis called.The base problem here is that the
react-leafletlibrary doesn't support this out of the box. However, we could get around this by:L.divIconto render a dummy div as the icon containing nothing. We will assign a unique ID for that div for each marker, which will come in handy later.Markercomponentsaddevent to detect when the icon has actually been rendered to the DOM.We can encapsulate this behaviour in an
EnhancedMarkercomponent, for ease of use.Here is a working CodeSandbox of the proof of concept. In this proof of concept, I am rendering two buttons as a marker, each with click events that work.
The below includes the generic code that can be applied to any situation:
For your example, you should be able to:
EnhancedMarkercomponent.<Marker>in your use case to<EnhancedMarker>.<IconGen />in the<EnhancedMarker>iconprop.