React拉取MySQL数据无法存入state,无法在谷歌地图展示用户位置求助
修复说明
核心问题1:setState异步特性导致的误解
React的状态更新是异步批量执行的,调用setSelectedPark后立刻打印状态,拿到的是更新前的旧值,并非数据没有存入state,组件触发重渲染后就能拿到更新后的值,可以在Map组件函数的第一行加打印验证重渲染后的状态。
核心问题2:单一状态承担多用途导致的类型冲突
你当前用同一个selectedPark状态同时存储「全部用户位置列表」和「当前选中的单个点位数据」,初始值为数组、请求后赋值为数组、点击标记点后赋值为对象、关闭弹窗后赋值为null,多种类型混用会导致.map调用报错等异常。
修复后代码
import { React, useState, useEffect } from "react"; import "./App.css"; import axios from "axios"; import { GoogleMap, withScriptjs, withGoogleMap, Marker, InfoWindow, } from "react-google-maps"; function Map() { // 拆分两个状态:1. 存储所有用户点位列表 2. 存储当前选中的单个点位 const [parkList, setParkList] = useState([]); const [selectedPark, setSelectedPark] = useState(null); var data = ""; var config = { method: "get", url: "http://localhost:3002/user", headers: {}, data: data, }; useEffect(() => { axios(config) .then(function (response) { console.log(JSON.stringify(response.data)); // 接口返回的列表存入parkList setParkList(response.data); }) .catch(function (error) { console.log(error); }); }, []); return ( <GoogleMap defaultZoom={10} defaultCenter={{ lat: 24.860966, lng: 66.990501 }} > {/* 遍历列表渲染标记点 */} {parkList.map((park) => ( <Marker key={park.user_Id} position={{ lat: park.latitude, lng: park.longitude, }} onClick={() => { setSelectedPark(park); }} icon={{ url: "https://raw.githubusercontent.com/leighhalliday/google-maps-react-demo/2bcd4ca7184ea9ed9edbc25021c2e721a74c027f/public/skateboarding.svg", scaledSize: new window.google.maps.Size(25, 25), }} /> ))} {selectedPark && ( <InfoWindow position={{ lat: selectedPark.latitude, lng: selectedPark.longitude, }} onCloseClick={() => { setSelectedPark(null); }} > <div> <h2>{selectedPark.area_name}</h2> <p>{selectedPark.area_description}</p> </div> </InfoWindow> )} </GoogleMap> ); } const WrappedApp = withScriptjs(withGoogleMap(Map)); function App() { return ( <div style={{ width: "100vw", height: "100vh" }}> <WrappedApp googleMapURL={`https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places&key=AIzaSyDmVpJ44AZEUIs-ml0R1Q0URcmr-Q-DMC4`} loadingElement={<div style={{ height: "100%" }} />} containerElement={<div style={{ height: "100%" }} />} mapElement={<div style={{ height: "100%" }} />} /> </div> ); } export default App;
额外调整说明
- 把原来App组件里的高度
100vw改为100vh,避免地图高度和宽度一致出现留白 - 把
onCloseClick事件移到了InfoWindow组件上,符合react-google-maps的API规范 - 请确认接口返回的字段和你InfoWindow里使用的
area_name、area_description匹配,无对应字段可自行调整展示内容
内容的提问来源于stack exchange,提问作者Yusra Masood
相关产品推荐
相关产品推荐

