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 prevEndRef = useRef();
|
||||
const prevDurationRef = useRef();
|
||||
const refitNeeded = useRef(false);
|
||||
|
||||
// Effect 1: Detects changes in `end` or `duration` and sets a flag.
|
||||
useEffect(() => {
|
||||
const prevEnd = prevEndRef.current;
|
||||
const prevDuration = prevDurationRef.current;
|
||||
|
||||
const endChanged = prevEnd && end.unix() !== prevEnd.unix();
|
||||
const durationChanged = prevDuration && duration.id !== prevDuration.id;
|
||||
// Run only after initial render where refs are populated.
|
||||
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);
|
||||
if (bounds.isValid()) {
|
||||
map.fitBounds(bounds);
|
||||
}
|
||||
// Reset the flag after the fit is performed.
|
||||
refitNeeded.current = false;
|
||||
}
|
||||
|
||||
prevEndRef.current = end;
|
||||
prevDurationRef.current = duration;
|
||||
}, [coords, mapState.center, map, end, duration]);
|
||||
}, [coords, mapState.center, map]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
Reference in New Issue
Block a user