[英]React.js State not updating in Event Listener in useEffect Hook
[英]React hook saved state in Event Listener wrong?
我有積分和一個更新積分的功能:
const [points, setPoints] = useState([])
const updatePoint = (updatedPoint) => {
setPoints(points.map(point => (point.id === updatedPoint.id ? updatedPoint : point)))
}
我向標記添加了一個偵聽器:
window.google.maps.event.addListener(marker, 'dragend',
function (markerLocal) {
console.log(getPoints)
}
)
如果創建后單擊第一個標記,它將在控制台中顯示1點。 如果我創建並單擊第二個,它會向我顯示2分,因此它將狀態保存在偵聽器內部。 但是,第二次保存后,第一個標記的點總和不變(被拖動時)。 這是正確的行為嗎? 如何獲得第一個標記的2分? 每當我嘗試更新點列表並單擊第一個標記時,它只會給我一個點-這是錯誤的。
這可能是因為處理程序在聲明時使用了這些points
,這些點可能會在調用之前進行更新。 我對此類問題的解決方案是將其定義為ref:
const points = useRef([]);
// This means that instead of `setPoints` you will do points.current = newValue
const updatePoint = (updatePoint) => {
points.current = points.current.map(...);
}
嘗試添加具有points
依賴性的useEffect並為Google地圖設置addEventListener。 此處的問題是初始addEventListener所作用的范圍。 在常規JS中,您將始終在范圍內擁有當前值,但是在掛鈎中,您的代碼將引用先前渲染中的陳舊值。 就您而言,您引用的是將事件附加到Google Maps時您的points
狀態所用的值。 我認為,這里最干凈的解決方案是Leftium的解決方案,但您也可以出於“學術”目的嘗試此解決方案:
const onGoogleMapsMarkerDragend = () => {
console.log(points);
}
useEffect(() => {
const dragendListener = window.google.maps.event.addListener(marker, 'dragend', onGoogleMapsMarkerDragend);
return () => {
window.google.maps.event.removeListener(dragendListener );
}
}, [points];
不確定removeListener是否有效-請查閱文檔
如果使用先前的狀態來計算新狀態,如您的示例,則應將舊狀態的函數而不是新值直接傳遞給setPoints()
:
const updatePoint = (updatedPoint) => {
setPoints((prevPoints) =>
prevPoints.map(point => (point.id === updatedPoint.id ? updatedPoint : point)
))
}
Hooks API參考中的相關部分: useState的功能更新
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.