socket?.on('addLocation', data => {
console.log('addLocation', data);
let isFound = false;
let newMarkers = markers.map(marker => {
if (marker.fleet_id == data.fleetId) {
isFound = false;
return {
...marker,
latitude: data.lat,
longitude: data.long,
};
} else {
return marker;
}
});
if (!isFound) {
newMarkers = [
...newMarkers,
{
fleet_id: data.fleetId,
latitude: data.lat,
longitude: data.long,
},
];
}
setMarker(newMarkers);
})
CodePudding user response:
Assuming markers
the state that setMarker
is updating then this appears to be an issue of a stale enclosure over the markers
state. The callback is updating the closed over state and not the current markers
state value.
Use a functional state update to correctly access the previous state instead of the stale value. Array.prototype.map
is meant to map one set of values to another, and shouldn't have side-effects like setting an isFound
flag. Search the data first to decide if the state needs to be updated or if a new element needs to be appended.
Example:
socket?.on('addLocation', data => {
console.log('addLocation', data);
setMarker(markers => {
const isFound = markers.some(marker => marker.fleet_id == data.fleetId);
if (isFound) {
return markers.map(marker => marker.fleet_id == data.fleetId
? {
...marker,
latitude: data.lat,
longitude: data.long,
}
: marker
);
}
return [
...markers,
{
fleet_id: data.fleetId,
latitude: data.lat,
longitude: data.long,
},
];
});
});
CodePudding user response:
socket?.on('addLocation', ({ fleetId, lat, long }) => {
setMarkers(existing => {
const latLng = { latitude: lat, longitude: long };
const index = existing.findIndex(m => m.fleet_id === fleetId);
if (index === -1) {
return [...existing, {
fleet_id: fleetId,
...latLng
}]
} else {
const clone = [...existing];
clone[index] = {
...clone[index],
...latLng
}
return clone;
}
});
});
There are a few things here:
- You should use the callback flavour of
setMarkers
to ensure you have the "latest" copy when you're modifying it. - The code as written is pretty convoluted, you can simplify it a lot.
isFound
will always be false is also a logic issue.