【问题标题】:Fetch data from backend for Google Map从谷歌地图的后端获取数据
【发布时间】:2019-10-31 02:27:53
【问题描述】:

我在这里关注本指南:https://youtu.be/Pf7g32CwX_s,了解如何使用 react-google-maps 添加谷歌地图。 Github 上的代码:https://github.com/leighhalliday/google-maps-react-demo/blob/master/src/App.js

我已经启动并运行了示例,但现在我想从后端获取数据,而不是在前端使用 json 文件。所以我有这个设置:

App.js

import React from 'react';

export async function stationsDataFunction() {
  const results = await fetch('http:...) ;
  return results.json();
}

class App extends React.Component {

  constructor(){
    super();
    this.state = {

    }
  }

  render(){
   return(
    <div className="App">
      <MapComponent/>
    </div>
    )
  }
}
export default App;

MapComponent.js

import React, {useState} from 'react';
import { GoogleMap, Marker, withScriptjs, withGoogleMap, InfoWindow } from "react-google-maps"
import {stationsDataFunction} from './App';

function Map(){
    console.log(stationsDataFunction()); // Line 14
    const stationsData = stationsDataFunction().then(response => {console.log(response); return response;}); // Line 15

    const [selectedStation, setSelectedStation] = useState(null); 
  return(
    <GoogleMap // Line 19
        defaultZoom={10}
        defaultCenter={{ lat: 63.0503, lng: 21.705826}}
      >
        {stationsData.features.map(station => (
          <Marker 
          key={station.properties.PARK_ID}
          position={{
            lat: station.geometry.coordinates[1], 
            lng: station.geometry.coordinates[0]
          }}
          onClick={(() => {
            setSelectedStation(station);
          })}
        />
        ))}

      //... more code here 

我正在将数据从后端返回到 const StationData,但似乎响应来得太晚了。我收到此错误:

未捕获的类型错误:无法读取未定义的属性“地图” 在地图 (MapComponent.js:19)

出现错误之前控制台打印出来:

MapComponent.js:14 承诺{待定}

出错后控制台打印出:

MapComponent.js:15 {type: "FeatureCollection", crs: {…}, features: Array(2)}

我不知道如何解决这个问题。


使用工作代码更新

App.js 工作代码

导出函数如下:

export async function stationsDataFunction() {

  const results = await fetch('http://localhost:4000/api/myData/stationNames') ;
  return results.json();
}

MapComponent.js 工作代码

import React, {useState, useEffect}  from 'react';
import { GoogleMap, Marker, withScriptjs, withGoogleMap, InfoWindow } from "react-google-maps"
import {stationsDataFunction} from './App';



function Map(){

  const [stationsData , setStationsData] = useState({ features: [] });
  const [selectedStation, setSelectedStation] = useState(null); 

  async function fetchStationsData() {
    const json = await stationsDataFunction();
    setStationsData(json);
  }
  useEffect(() => {
    fetchStationsData();
  }, []);


  return(
    <GoogleMap
        defaultZoom={10}
        defaultCenter={{ lat: 63.0503, lng: 21.705826}}
      >
        {stationsData.features && stationsData.features.map(station => (
          <Marker 
          key={station.properties.PARK_ID}
          position={{
            lat: station.geometry.coordinates[1], 
            lng: station.geometry.coordinates[0]
          }}
// More code here

【问题讨论】:

    标签: javascript json reactjs google-maps react-hooks


    【解决方案1】:

    你的代码中的问题是你在这里有一个异步调用

    const stationsData = stationsDataFunction().then(response => {console.log(response); return response;});
    

    但是当您尝试访问数据stationsData.features 时,features 是未定义的,因为承诺尚未解决。

    你可以做的是条件渲染

    {stationsData.features && stationsData.features.map(...)}
    

    但也许,这不能解决您的问题,您需要使用 useEffect 钩子。

    import React, {useState, useEffect} from 'react';
    
    function Map(){
        const [stationsData , setStationsData] = useState({}); 
        const [selectedStation, setSelectedStation] = useState(null); 
    
        useEffect(() => { 
            stationsDataFunction().then(response => {console.log(response); setStationsData(response);});
        }, [])
    
        return(
            <GoogleMap // Line 19
                defaultZoom={10}
                defaultCenter={{ lat: 63.0503, lng: 21.705826}}
            >
                {stationsData.features && stationsData.features.map(...)
            ...
    

    【讨论】:

    • 我收到此错误:警告:效果函数不得返回除用于清理的函数之外的任何内容。看起来你写了 useEffect(async () => ...) 或返回了一个 Promise。相反,在你的效果中编写异步函数并立即调用它: useEffect(() => { async function fetchData() { // 你可以在这里等待 const response = await MyAPI.getData(someId); // ... } fetchData(); }, [someId]); // 如果效果不需要道具或状态,则为 []
    • @Crocky 刚刚修正了我的答案,我忘了添加一些{}xD
    【解决方案2】:

    没错,一旦标记被渲染,数据还没有加载。

    改动列表:

    a) 像这样初始化 default 值(防止'map' of undefined error):

    const [stationsData, setStationsData] = useState({ features: [] });
    

    b) 使用Effect Hook 获取数据:

    useEffect(() => {
       fetchStationsData();
    }, []);
    

    在哪里

    async function fetchStationsData() {
       const json = await stationsDataFunction();
       setStationsData(json);
    }
    

    示例

    function Map(props) {
      const [data, setData] = useState([{ features: [] }]);
    
      async function fetchData() {
        const results = await fetch(
          "https://raw.githubusercontent.com/leighhalliday/google-maps-react-demo/master/src/data/skateboard-parks.json"
        );
        const json = await results.json();
        setData(json.features)
      }
    
      useEffect(() => {
        fetchData();
      }, []);
    
      return (
        <GoogleMap defaultZoom={props.zoom} defaultCenter={props.center}>
          {data.map(item => (
            <Marker key={item.properties.PARK_ID} position={{
              lat: item.geometry.coordinates[1], 
              lng: item.geometry.coordinates[0]
            }} />
          ))}
        </GoogleMap>
      );
    }
    

    【讨论】:

    • 据我了解,stationsData 包含获取的数据,而 selectedStation 仅包含选定的电台。你的答案假设它们是相同的?
    • @Crocky,我猜你明白了,因为selectedStation 被保留用于存储选定的电台,stationsData 状态被引入来存储所有电台。答案已更新
    • 谢谢,现在好像没问题了。我正在用最终代码更新我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-06
    • 2013-07-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-24
    • 2021-10-08
    • 1970-01-01
    相关资源
    最近更新 更多