Skip to content

Commit

Permalink
perf: use useCallbacks for handlers and deconstruct events (#7004)
Browse files Browse the repository at this point in the history
* wrap map handlers in useCallbacks

* deconstruct events

---------

Co-authored-by: Tony <tony.vanswet@electricitymaps.com>
  • Loading branch information
VIKTORVAV99 and tonypls authored Aug 8, 2024
1 parent 0513307 commit d76b2b4
Showing 1 changed file with 88 additions and 78 deletions.
166 changes: 88 additions & 78 deletions web/src/features/map/Map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -230,117 +230,127 @@ export default function MapPage({ onMapLoad }: MapPageProps): ReactElement {
setLeftPanelOpen,
]);

const onClick = (event: maplibregl.MapLayerMouseEvent) => {
if (!map || !event.features) {
return;
}
const feature = event.features[0];

// Remove state from old feature if we are no longer hovering anything,
// or if we are hovering a different feature than the previous one
if (selectedZoneId && (!feature || selectedZoneId !== feature.id)) {
map.setFeatureState(
{ source: ZONE_SOURCE, id: selectedZoneId },
{ selected: false }
);
}

if (hoveredZone && (!feature || hoveredZone.featureId !== selectedZoneId)) {
map.setFeatureState(
{ source: ZONE_SOURCE, id: hoveredZone.featureId },
{ hover: false }
);
}
setHoveredZone(null);
if (feature?.properties) {
const zoneId = feature.properties.zoneId;
navigate(createToWithState(`/zone/${zoneId}`));
} else {
navigate(createToWithState('/map'));
}
};
const onClick = useCallback(
({ features }: maplibregl.MapLayerMouseEvent) => {
if (!map || !features) {
return;
}
const feature = features[0];

// TODO: Consider if we need to ignore zone hovering if the map is dragging
const onMouseMove = (event: maplibregl.MapLayerMouseEvent) => {
if (!map || !event.features) {
return;
}
const feature = event.features[0];
const isHoveringAZone = feature?.id !== undefined;
const isHoveringANewZone = isHoveringAZone && hoveredZone?.featureId !== feature?.id;
// Remove state from old feature if we are no longer hovering anything,
// or if we are hovering a different feature than the previous one
if (selectedZoneId && (!feature || selectedZoneId !== feature.id)) {
map.setFeatureState(
{ source: ZONE_SOURCE, id: selectedZoneId },
{ selected: false }
);
}

// Reset currently hovered zone if we are no longer hovering anything
if (!isHoveringAZone && hoveredZone) {
if (hoveredZone && (!feature || hoveredZone.featureId !== selectedZoneId)) {
map.setFeatureState(
{ source: ZONE_SOURCE, id: hoveredZone.featureId },
{ hover: false }
);
}
setHoveredZone(null);
map.setFeatureState(
{ source: ZONE_SOURCE, id: hoveredZone?.featureId },
{ hover: false }
);
}

// Do no more if we are not hovering a zone
if (!isHoveringAZone) {
return;
}
if (feature?.properties) {
const zoneId = feature.properties.zoneId;
navigate(createToWithState(`/zone/${zoneId}`));
} else {
navigate(createToWithState('/map'));
}
},
[map, selectedZoneId, hoveredZone, setHoveredZone, navigate]
);

// Update mouse position to help position the tooltip
setMousePosition({
x: event.point.x,
y: event.point.y,
});
// TODO: Consider if we need to ignore zone hovering if the map is dragging
const onMouseMove = useCallback(
({ features, point }: maplibregl.MapLayerMouseEvent) => {
if (!map || !features) {
return;
}
const feature = features[0];
const isHoveringAZone = feature?.id !== undefined;
const isHoveringANewZone =
isHoveringAZone && hoveredZone?.featureId !== feature?.id;

// Update hovered zone if we are hovering a new zone
if (isHoveringANewZone) {
// Reset the old one first
if (hoveredZone) {
// Reset currently hovered zone if we are no longer hovering anything
if (!isHoveringAZone && hoveredZone) {
setHoveredZone(null);
map.setFeatureState(
{ source: ZONE_SOURCE, id: hoveredZone?.featureId },
{ hover: false }
);
}

setHoveredZone({ featureId: feature.id, zoneId: feature.properties?.zoneId });
map.setFeatureState({ source: ZONE_SOURCE, id: feature.id }, { hover: true });
}
};
// Do no more if we are not hovering a zone
if (!isHoveringAZone) {
return;
}

// Update mouse position to help position the tooltip
setMousePosition({
x: point.x,
y: point.y,
});

// Update hovered zone if we are hovering a new zone
if (isHoveringANewZone) {
// Reset the old one first
if (hoveredZone) {
map.setFeatureState(
{ source: ZONE_SOURCE, id: hoveredZone?.featureId },
{ hover: false }
);
}

const onMouseOut = () => {
setHoveredZone({ featureId: feature.id, zoneId: feature.properties?.zoneId });
map.setFeatureState({ source: ZONE_SOURCE, id: feature.id }, { hover: true });
}
},
[map, hoveredZone, setHoveredZone, setMousePosition]
);

const onMouseOut = useCallback(() => {
if (!map) {
return;
}

// Reset hovered state when mouse leaves map (e.g. cursor moving into panel)
// Reset hovered state when mouse leaves map (e.g., cursor moving into panel)
if (hoveredZone?.featureId !== undefined) {
map.setFeatureState(
{ source: ZONE_SOURCE, id: hoveredZone?.featureId },
{ hover: false }
);
setHoveredZone(null);
}
};
}, [map, hoveredZone, setHoveredZone]);

const onError = (event: ErrorEvent) => {
console.error(event.error);
setIsLoadingMap(false);
// TODO: Show error message to user
// TODO: Send to Sentry
// TODO: Handle the "no webgl" error gracefully
};
const onError = useCallback(
({ error }: ErrorEvent) => {
console.error(error);
setIsLoadingMap(false);
// TODO: Show error message to user
// TODO: Send to Sentry
// TODO: Handle the "no webgl" error gracefully
},
[setIsLoadingMap]
);

const onLoad = () => {
const onLoad = useCallback(() => {
setIsLoadingMap(false);
if (onMapLoad && mapReference) {
onMapLoad(mapReference.getMap());
}
};
}, [setIsLoadingMap, onMapLoad, mapReference]);

const onMoveStart = () => {
const onMoveStart = useCallback(() => {
setIsMoving(true);
};
}, [setIsMoving]);

const onMoveEnd = () => {
const onMoveEnd = useCallback(() => {
setIsMoving(false);
};
}, [setIsMoving]);

return (
<Map
Expand Down

0 comments on commit d76b2b4

Please sign in to comment.