我目前正在尝试循环遍历一个数组,并在我的react应用程序中的谷歌地图上显示多个标记。我首先必须通过地理编码api来运行位置,以获得lat和lng,然后设置一个状态变量来映射,以将标记显示在地图上。我目前在代码中的某个地方遇到问题,似乎找不到问题。
我知道,当我console.log我的状态变量时,它似乎会运行日志好几次,前几次是空数组,最后几次包含我需要的数据。我是一个新的反应者,仍在努力掌握它。
另外,我认为我的.map函数在设置状态变量之前就已经运行了,我不知道如何进行重构。
这是我的代码-
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>
)
}