英文:
How to understand that behavior of useState?
问题
以下是您提供的代码的翻译部分:
有一个自定义钩子:
function useMap(mapRef, location) {
const [map, setMap] = useState(null)
useEffect(() => {
if (mapRef.current !== null && map === null) {
const instance = leaflet.createMap(mapRef, location) // упрощенный код
setMap(instance)
}
}, [map, location])
return map;
}
此钩子在从服务器传递的属性的组件中调用:
function Map({ location }) {
const mapRef = useRef(null)
const map = useMap(mapRef, location)
return (
<div
ref={mapRef}
style={{ height: height }}
/>
)
}
我的问题是,在组件的第一次渲染之后,useMap
中调用了 setMap
。该组件的后续渲染几乎立即发生(因为location
快速来自服务器)。在同一个钩子中,useMap
的 map
仍然为 null
,而不是我们在先前的渲染中传递给 setMap
的值。过一段时间后,map
仍然会更新,但这可能发生在第二、第三和第四次渲染上。
我曾经理解 setState,如果在前一个渲染器上调用,下一个渲染器会准确获取传递给此 setState 的值。
我尝试查阅了 React 的完整文档。
英文:
There is a custom hook:
function useMap(mapRef, location) {
const [map, setMap] = useState(null)
useEffect(() => {
if (mapRef.current !== null && map === null) {
const instance = leaflet.createMap(mapRef, location)//упрощенный код
setMap(instance)
}
}, [map, location])
return map;
}
This hook is called in a component that has props coming from the server.
function Map({ location }) {
const mapRef = useRef(null)
const map = useMap(mapRef, location)
return (
<div
ref={mapRef}
style={{ height: height }}
/>
)
}
My problem is that after the first render of the component, the setMap is called in useMap. The next renders of this component occur almost immediately (since the location comes from the server quickly). In the same hook, useMap Map remains null
, and not what we passed in the previous render in setMap. After some time, the Map is still updated, but this can happen on 2nd, 3rd, and 4th renders.
There was an understanding in my head that setState, if it was called on the previous renderer, on the next renderer exactly takes the value passed to this setState.
I tried to check whole documentation of react.
答案1
得分: 1
您可以通过使用setMap的回调形式来避免重新渲染,这使您可以基于先前的值提供值:
function useMap(mapRef, location) {
const [map, setMap] = useState(null)
useEffect(() => {
setMap(existingMap => {
if (mapRef.current !== null && existingMap === null) {
return leaflet.createMap(mapRef, location);
} else {
return existingMap;
}
});
}, [setMap, location])
return map;
}
英文:
You can avoid the re-render by using the callback form of setMap
which lets you provided value based on the previous value:
function useMap(mapRef, location) {
const [map, setMap] = useState(null)
useEffect(() => {
setMap(existingMap => {
if (mapRef.current !== null && existingMap === null) {
return leaflet.createMap(mapRef, location);
} else {
return existingMap;
}
});
}, [setMap, location])
return map;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论