React Leaflet Map Popup Re-rendering Problem

67 Views Asked by At

I have this code for Leaflet map where the popup content of markers is dynamically created for every unique profile ID.Markers are creating from data which arrives from WebSocket. However, each time new data arrives, the popup is being re-rendered. How can I prevent the popup from re-rendering?

const DashboardMap: React.FC = () => {
    const [socket, setSocket] = useState<WebSocket | null>(null);
    const [isConnected, setIsConnected] = useState(false);
    const [dataMap, setDataMap] = useState<Record<string, SummaryMapData>>({});
    const [localTotalActivities, setLocalTotalActivities] = useState<Record<string, number>>({});
    const [summaryMapData, setSummaryMapData] = useState<SummaryMapData | null>(null);
    const [selectedActivities, setSelectedActivities] = useState<string[]>(['mdmResponse', 'ecrResponse', 'eventHeartBeat', 'eventTransaction', 'eventLog', 'eventSystem', 'logOn']);
 
  newSocket.onmessage = (event) => {
            const data = JSON.parse(event.data) as SummaryMapData;
            setSummaryMapData(data);
            console.log(data);
        };
 const updateDataMap = (summaryMapData: SummaryMapData) => {
        if (summaryMapData?.hasOwnProperty('profileId')) {
            const profileId = summaryMapData.profileId;
            setDataMap(prevDataMap => {
                const prevProfileData = prevDataMap[profileId] || {
                    type: "",
                    profileId: "",
                    bank: "",
                    merchant: "",
                    timestamp: "",
                    init: 0,
                    mdmResponse: 0,
                    ecrResponse: 0,
                    eventHeartBeat: 0,
                    eventTransaction: 0,
                    eventLog: 0,
                    eventSystem: 0,
                    logOn: 0,
                    latitude: 0,
                    longitude: 0,
                    totalActivities: 0,
                };

                const newTotalActivities = (prevProfileData.totalActivities || 0) + 1;

                setLocalTotalActivities(prevLocalTotalActivities => ({
                    ...prevLocalTotalActivities,
                    [profileId]: newTotalActivities,
                }));

                return {
                    ...prevDataMap,
                    [profileId]: {
                        ...prevProfileData,
                        ...summaryMapData,
                        timestamp: prevProfileData.timestamp > summaryMapData.timestamp ? prevProfileData.timestamp : summaryMapData.timestamp,
                        totalActivities: newTotalActivities,
                        init: prevProfileData.init + (summaryMapData.init || 0),
                        mdmResponse: prevProfileData.mdmResponse + (summaryMapData.mdmResponse || 0),
                        ecrResponse: prevProfileData.ecrResponse + (summaryMapData.ecrResponse || 0),
                        eventHeartBeat: prevProfileData.eventHeartBeat + (summaryMapData.eventHeartBeat || 0),
                        eventTransaction: prevProfileData.eventTransaction + (summaryMapData.eventTransaction || 0),
                        eventLog: prevProfileData.eventLog + (summaryMapData.eventLog || 0),
                        eventSystem: prevProfileData.eventSystem + (summaryMapData.eventSystem || 0),
                        logOn: prevProfileData.logOn + (summaryMapData.logOn || 0),
                    },
                };
            });
        }
    };

    useEffect(() => {
        if (summaryMapData) {
            updateDataMap(summaryMapData);
        }
    }, [summaryMapData]);
 <MapContainer center={[42.6507, 18.0944]} zoom={5} fullscreenControl={true} style={{height: "300px"}}>
                <TileLayer
                    attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
                    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                />
                map = useMap();
                <MarkerClusterGroup>
                    {filteredMarkers.map(([profileId, data], index) => (
                        <Marker
                            key={profileId}
                            position={[data.latitude, data.longitude]}
                            icon={customIcon}
                        >
                            <Popup key={profileId}>
                                <div>
                                    <strong>Profile ID:</strong> {data.profileId} <br/>
                                    <strong>Bank:</strong> {data.bank || 'N/A'} <br/>
                                    <strong>Time ago:</strong> {getTimeAgoString(data.timestamp)} <br/>
                                    <strong>Merchant:</strong> {data.merchant || 'N/A'} <br/>
                                    <strong>Inits:</strong> {data.init || 0} <br/>
                                    <strong>Mdm events:</strong> {data.mdmResponse || 0} <br/>
                                    <strong>Ecr events:</strong> {data.ecrResponse || 0} <br/>
                                    <strong>Heartbeats:</strong> {data.eventHeartBeat || 0} <br/>
                                    <strong>Transactions:</strong> {data.eventTransaction || 0} <br/>
                                    <strong>Logs:</strong> {data.eventLog || 0} <br/>
                                    <strong>System events:</strong> {data.eventSystem || 0} <br/>
                                    <strong>Logons:</strong> {data.logOn || 0} <br/>
                                    <strong>Total Activities:</strong> {localTotalActivities[data.profileId] || 0}
                                    <br/>
                                </div>
                            </Popup>
                            {index === 0 && <RecenterAutomatically lat={data.latitude} lng={data.longitude} zoom={5}/>}
                        </Marker>
                    ))}

                </MarkerClusterGroup>
            </MapContainer>

I have attempted to use useMemo and other techniques, but I haven't been able to prevent the popup from re-rendering every time new data arrives. My goal is for the popup to update only the fields that have changed, rather than re-rendering entirely

0

There are 0 best solutions below