fix: Resolve race condition when refitting map on date change
This commit is contained in:
@@ -111,24 +111,41 @@ function FitBounds({ coords, mapState, end, duration }) {
|
|||||||
const map = useMap();
|
const map = useMap();
|
||||||
const prevEndRef = useRef();
|
const prevEndRef = useRef();
|
||||||
const prevDurationRef = useRef();
|
const prevDurationRef = useRef();
|
||||||
|
const refitNeeded = useRef(false);
|
||||||
|
|
||||||
|
// Effect 1: Detects changes in `end` or `duration` and sets a flag.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const prevEnd = prevEndRef.current;
|
const prevEnd = prevEndRef.current;
|
||||||
const prevDuration = prevDurationRef.current;
|
const prevDuration = prevDurationRef.current;
|
||||||
|
|
||||||
const endChanged = prevEnd && end.unix() !== prevEnd.unix();
|
// Run only after initial render where refs are populated.
|
||||||
const durationChanged = prevDuration && duration.id !== prevDuration.id;
|
if (prevEnd && prevDuration) {
|
||||||
|
const endChanged = end.unix() !== prevEnd.unix();
|
||||||
|
const durationChanged = duration.id !== prevDuration.id;
|
||||||
|
|
||||||
if ((mapState.center === null || endChanged || durationChanged) && coords.length > 0) {
|
if (endChanged || durationChanged) {
|
||||||
|
refitNeeded.current = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update refs for the next render's comparison.
|
||||||
|
prevEndRef.current = end;
|
||||||
|
prevDurationRef.current = duration;
|
||||||
|
}, [end, duration]);
|
||||||
|
|
||||||
|
// Effect 2: Acts on `coords` changes, but only if the flag is set.
|
||||||
|
useEffect(() => {
|
||||||
|
// A refit is needed on initial load (mapState.center is null)
|
||||||
|
// or if the flag has been set by the other effect.
|
||||||
|
if ((mapState.center === null || refitNeeded.current) && coords.length > 0) {
|
||||||
const bounds = leaflet.latLngBounds(coords);
|
const bounds = leaflet.latLngBounds(coords);
|
||||||
if (bounds.isValid()) {
|
if (bounds.isValid()) {
|
||||||
map.fitBounds(bounds);
|
map.fitBounds(bounds);
|
||||||
}
|
}
|
||||||
|
// Reset the flag after the fit is performed.
|
||||||
|
refitNeeded.current = false;
|
||||||
}
|
}
|
||||||
|
}, [coords, mapState.center, map]);
|
||||||
prevEndRef.current = end;
|
|
||||||
prevDurationRef.current = duration;
|
|
||||||
}, [coords, mapState.center, map, end, duration]);
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user