google 地图上的多个标记 React with a .map

Multiple markers on google map React with a .map

我目前正在尝试遍历数组并在我的 React 应用程序的 google 地图上显示多个标记。我首先必须通过地理编码 api 运行 位置来获取纬度和经度,然后设置一个状态变量进行映射以使标记显示在地图上。我目前在我的代码中的某处遇到问题,似乎找不到问题所在。

我知道当我 console.log 我的状态变量时,它似乎 运行 日志几次,前几次是空数组,最后几次包含我需要的数据。我对反应还很陌生,仍在努力掌握它。

此外,我认为我的 .map 函数在设置状态变量之前 运行ning,我不确定如何重构来解决这个问题。

这是我的代码 -

import React, { useContext, useEffect, useState } from 'react';
import { GoogleMap, useLoadScript, Marker } from "@react-google-maps/api"
import Settings from "../Settings"
import mapSyles from "./MapStyles"
import { LogContext } from '../divelog/DiveLogProvider';

export const MapRender =(props) => {
    const {diveLogs} = useContext(LogContext)
    const [latLong, setLatLong] = useState([])
    

    
     useEffect(()=>{
    //Taking the logs and running them through API to get lat and lng for each location 
    let latLongs = []
    diveLogs.map(dl =>{
        return fetch(`http://api.positionstack.com/v1/forward?access_key=ff0fcd042ab984146219abc275c71e4b&query=${dl.location}&limit=1
        `)
            .then(res => res.json())
            .then(parsedRes => {

                latLongs.push(parsedRes.data[0])
                setLatLong(latLongs)
              })


    })
 
},[diveLogs])


// this returns several logs, the first of which are empty arrays and the last are correct with the data that I need
    console.log(latLong)

    


    const { isLoaded, loadError } = useLoadScript({
        googleMapsApiKey: Settings.apiKey
    })

    const mapContainerStyle = {
        width: '31rem',
        height: '24rem'
    }

    const center = {
        lat: 0,
        lng: 0
    }

    const options = {
        styles: mapSyles,
        disableDefaultUI: true
    }


    
    if (loadError) console.log("error loading maps")
    if (!isLoaded) return "Loading..."

    return (
        <div>
            <GoogleMap
                mapContainerStyle={mapContainerStyle}
                options={options}
                zoom={1}
                center={center}
            >
                
                {
                    //this is where I map through the state variable
                    latLong.map(l =>(
                     <Marker key={l.lat}
                         position ={{lat: l.latitude, lng: l.longitude}} 
                         />
                    ))
                }
            </GoogleMap>
        </div>
    )
}

您需要将 setLatLong(myDiveLogs) 移动到 api 调用的成功方法中。 Api 调用是异步的,但在 setLatLong 中分配数据是同步的。 React 将在 setLatLong 中推送空数据。

您需要等待 api 调用,一旦数据可用,请在其中设置值。

import React, {
  useContext,
  useEffect,
  useState
} from 'react';
import {
  GoogleMap,
  useLoadScript,
  Marker
} from "@react-google-maps/api"
import Settings from "../Settings"
import mapSyles from "./MapStyles"
import {
  LogContext
} from '../divelog/DiveLogProvider';

export const MapRender = (props) => {
  const {
    diveLogs
  } = useContext(LogContext)
  const [latLong, setLatLong] = useState([])



  useEffect(() => {
    //Taking the logs and running them through API to get lat and lng for each location 
    let myDiveLogs = []
    diveLogs.map(dl => {
      return fetch(`http://api.positionstack.com/v1/forward?access_key=MYKEY&query=${dl.location}&limit=1
            `)
        .then(res => res.json())
        .then(parsedRes => {

          myDiveLogs.push(parsedRes.data[0])
          setLatLong(myDiveLogs)
        })


    })

  }, [diveLogs])

  // this returns several logs, the first of which are empty arrays and the last are correct with the data that I need
  console.log(latLong)




  const {
    isLoaded,
    loadError
  } = useLoadScript({
    googleMapsApiKey: Settings.apiKey
  })

  const mapContainerStyle = {
    width: '31rem',
    height: '24rem'
  }

  const center = {
    lat: 0,
    lng: 0
  }

  const options = {
    styles: mapSyles,
    disableDefaultUI: true
  }



  if (loadError) console.log("error loading maps")
  if (!isLoaded) return "Loading..."

  return ( <
    div >
    <
    GoogleMap mapContainerStyle = {
      mapContainerStyle
    }
    options = {
      options
    }
    zoom = {
      1
    }
    center = {
      center
    } >

    {
      //this is where I map through the state variable
      latLong.map(l => ( <
        Marker key = {
          l.lat
        }
        position = {
          {
            lat: l.latitude,
            lng: l.longitude
          }
        }
        />
      ))
    } <
    /GoogleMap> <
    /div>
  )
}