React useEffect运行延迟,传给react-leaflet的props初始值丢失如何解决
问题根因
useEffect回调会在组件首次渲染完成后才执行,加上getIp是异步请求,所以首次渲染时传递给react-leaflet组件的是useState设置的初始值[0,0],等异步请求返回后才会更新state触发重渲染,这是控制台输出两次值的原因。- react-leaflet的
MapContainer组件的center等初始化属性默认仅在地图实例创建时读取一次,后续state更新不会自动同步到地图实例,所以会出现更新后的坐标不生效的问题。
解决方案
方案1:等待坐标获取完成后再渲染地图
通过条件渲染跳过初始无效值的传递,等拿到真实坐标再加载地图组件:
const [map, setMap] = useState(null); useEffect(() => { const data = getIp(); data.then(result => { setMap([result.lat, result.lon]); }) }, []) // 未拿到坐标时展示加载态 if (!map) return <div>地图加载中...</div> // 拿到坐标后再渲染地图 return ( <MapContainer center={map} zoom={13}> {/* 其他地图子组件 */} </MapContainer> )
方案2:提前渲染地图,后续手动更新坐标
如果需要先渲染地图骨架,后续异步更新位置,可以使用react-leaflet提供的useMap hook手动同步坐标:
// 封装坐标更新子组件(必须放在MapContainer内部使用) function UpdateMapCenter({ center }) { const map = useMap(); useEffect(() => { // 坐标变化时调用地图实例方法更新视图 map.setView(center, map.getZoom()); }, [center]) return null; } // 父组件逻辑 const [map, setMap] = useState([0, 0]); useEffect(() => { const data = getIp(); data.then(result => { setMap([result.lat, result.lon]); }) }, []) return ( <MapContainer center={map} zoom={13}> <UpdateMapCenter center={map} /> {/* 其他地图子组件 */} </MapContainer> )
内容的提问来源于stack exchange,提问作者user14752038
相关产品推荐
相关产品推荐

