I have points and a function to update points:
const [points, setPoints] = useState([])
const updatePoint = (updatedPoint) => {
setPoints(points.map(point => (point.id === updatedPoint.id ? updatedPoint : point)))
}
I've added a Listener to the marker:
window.google.maps.event.addListener(marker, 'dragend',
function (markerLocal) {
console.log(getPoints)
}
)
If I click on first marker after I've created it, it shows me 1 point in the console. If I create and click second it shows me 2 points, So it saves the state inside of the listener. However, after the second save, the sum of points for the first marker doesn't change(when it gets dragged). Is this the right behaviour? How can I get two points for the first marker? Whenever I try to update my point list and click the 1st marker, it gives me only one point - that's wrong.
I have points and a function to update points:
const [points, setPoints] = useState([])
const updatePoint = (updatedPoint) => {
setPoints(points.map(point => (point.id === updatedPoint.id ? updatedPoint : point)))
}
I've added a Listener to the marker:
window.google.maps.event.addListener(marker, 'dragend',
function (markerLocal) {
console.log(getPoints)
}
)
If I click on first marker after I've created it, it shows me 1 point in the console. If I create and click second it shows me 2 points, So it saves the state inside of the listener. However, after the second save, the sum of points for the first marker doesn't change(when it gets dragged). Is this the right behaviour? How can I get two points for the first marker? Whenever I try to update my point list and click the 1st marker, it gives me only one point - that's wrong.
Share Improve this question edited Feb 21, 2019 at 12:17 Clydeston 271 silver badge9 bronze badges asked Feb 21, 2019 at 12:06 Pashuk xCodePashuk xCode 811 silver badge8 bronze badges 1-
I think you may need to show more of your code - what is
getPoints
? Where are you setting up your listeners? – Joe Clay Commented Feb 21, 2019 at 12:44
3 Answers
Reset to default 7Try adding useEffect with points
dependency and set addEventListener for google maps. An issue here is the scope that the initial addEventListener is working on. In regular JS you would always have the current value in the scope, however, in hooks, your code will reference stale values from previous renders. In your case, you are referencing the values your points
state was at the time of attaching the event to Google Maps. The cleanest solution here, in my opinion, is the Leftium's one, but you can also try this one for 'academic' purposes:
const onGoogleMapsMarkerDragend = () => {
console.log(points);
}
useEffect(() => {
const dragendListener = window.google.maps.event.addListener(marker, 'dragend', onGoogleMapsMarkerDragend);
return () => {
window.google.maps.event.removeListener(dragendListener );
}
}, [points];
Not sure if removeListener is valid - check with the documentation
This is probably because the handler uses the points
at the time of declaration, which might be updated before it is invoked. My solution to such issues was to define it as a ref:
const points = useRef([]);
// This means that instead of `setPoints` you will do points.current = newValue
const updatePoint = (updatePoint) => {
points.current = points.current.map(...);
}
If a previous state is used to calculate the new state, as in your example, you should pass setPoints()
a function of the old state instead of the new value directly:
const updatePoint = (updatedPoint) => {
setPoints((prevPoints) =>
prevPoints.map(point => (point.id === updatedPoint.id ? updatedPoint : point)
))
}
Relevant section from Hooks API Reference: Functional updates for useState