这是我的状态:
const [markers, setMarkers] = useState([])
我在 useEffect Hook 中初始化了 Leaflet map 。它有一个 click
事件处理程序。
useEffect(() => {
map.current = Leaflet.map('mapid').setView([46.378333, 13.836667], 12)
.
.
.
map.current.on('click', onMapClick)
}, []
在 onMapClick
中,我在 map 上创建了一个标记并将其添加到状态:
const onMapClick = useCallback((event) => {
console.log('onMapClick markers', markers)
const marker = Leaflet.marker(event.latlng, {
draggable: true,
icon: Leaflet.divIcon({
html: markers.length + 1,
className: 'marker-text',
}),
}).addTo(map.current).on('move', onMarkerMove)
setMarkers((existingMarkers) => [ ...existingMarkers, marker])
}, [markers, onMarkerMove])
但我也想在这里访问 markers
状态。但是我无法在此处阅读标记
。它始终是初始状态。我试图通过按钮的 onClick 处理程序调用 onMapClick
。在那里我可以阅读标记
。如果原始事件在 map 上开始,为什么我无法读取 markers
?如何读取 onMapClick
中的状态变量?
这是一个例子:https://codesandbox.io/s/jolly-mendel-r58zp?file=/src/map4.js
当您在 map 中单击并查看控制台时,您会看到 onMapClick
中的 markers
数组在 useEffect
中填充时保持为空> 监听标记
。
最佳答案
React 状态是异步的,它不会立即保证给你新的状态,至于你的问题如果原始事件从 map 开始,我为什么不能读取标记这是一个异步性质以及状态值被函数基于其当前闭包使用的事实和状态更新将反射(reflect)在下一次重新渲染中,现有闭包不会受到影响但会创建新闭包,这个问题你不会在类组件上遇到因为你有 this 实例,它具有全局范围。
作为开发组件,我们应该确保组件是从您调用它的地方控制的,而不是处理状态的函数闭包,它会在每次状态更改时重新呈现。您的解决方案是可行的,您应该在需要时将值传递给您传递给函数的任何事件或操作。
编辑:- 它很简单,只需将参数或 deps 传递给 useEffect 并将您的回调包装在里面,对于您的情况就是
useEffect(() => {
map.current = Leaflet.map('mapid').setView([46.378333, 13.836667], 12)
.
.
.
map.current.on('click',()=> onMapClick(markers)) //pass latest change
}, [markers] // when your state changes it will call this again
有关更多信息,请查看此信息 https://dmitripavlutin.com/react-hooks-stale-closures/ ,它将对您有更长远的帮助!!!
关于reactjs - 如何在我的事件处理程序中访问 React 状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63307310/