You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 00:36:04