几天来,我一直在尝试将标记放置在Google地图上的坐标上,但遇到此错误:
对象作为React子对象无效(发现:[object Promise])
因此,我发现可以使用Promise.all
来解决此问题,但是在正确执行此操作时遇到了麻烦。我不完全确定应该在组件中的方式和位置。
有人可以帮我吗?
代码如下:
import React, { Component } from "react";
import { Map, InfoWindow, Marker, GoogleApiWrapper } from "google-maps-react";
import Navbar from "./Navbar";
import { connect } from "react-redux";
import { getVacations } from "./redux";
import Geocode from "react-geocode";
class GoogleMaps extends Component {
constructor() {
super();
this.state = {
coords: []
}
}
componentDidMount = () => {
this.props.getVacations();
}
render() {
console.log(this.props);
const coordinates = this.props.vacations.map(coordinate => {
const convert = Geocode.fromAddress(coordinate.location);
return convert;
})
Promise.all(coordinates).then(locations => {
const markers = locations.map(place => {
console.log(place);
const lat = place.results[0].geometry.location.lat;
const lng = place.results[0].geometry.location.lng;
return [
<Marker
key={place._id}
position={
{
lat: lat,
lng:lng
}
}
animation={2}
/>
]
})
this.setState({
coords: markers
})
})
return (
<div>
<Navbar />
<Map
google={this.props.google}
zoom={4}
>
{this.state.coords}
</Map>
</div>
)
}
}
const connectVaca = connect(state => ({vacations: state}), {getVacations})(GoogleMaps);
export default GoogleApiWrapper({
apiKey: "API KEY HERE"
})(connectVaca)
这是我的getVacations动作和减速器:
export const getVacations = () => {
return dispatch => {
axios.get("/vacations").then(response => {
dispatch({
type: "GET_VACATIONS",
vacations: response.data
})
}).catch(err => {
console.log(err);
})
}
}
const reducer = (state = [], action) => {
switch(action.type){
case "GET_VACATIONS":
return action.vacations;
default:
return state;
}
}
答案 0 :(得分:1)
render方法中不应包含异步函数调用。根据react文档,异步调用的最佳位置是componentDidMount
。
将您的Promise.all
调用放入componentDidMount
函数中。无论何时安装组件,都会执行此功能。然后,只要调用setState
来设置coords
,您的组件就会使用更新后的coords
值重新呈现。
import React, { Component } from "react";
import { Map, InfoWindow, Marker, GoogleApiWrapper } from "google-maps-react";
import Navbar from "./Navbar";
import { connect } from "react-redux";
import { getVacations } from "./redux";
import Geocode from "react-geocode";
class GoogleMaps extends Component {
constructor() {
super();
this.state = {
coords: []
}
}
componentDidMount = () => {
this.props.getVacations();
const coordinates = this.props.vacations.map(coordinate => {
const convert = Geocode.fromAddress(coordinate.location);
return convert;
})
Promise.all(coordinates).then(locations => {
const markers = locations.map(place => {
console.log(place);
const lat = place.results[0].geometry.location.lat;
const lng = place.results[0].geometry.location.lng;
return (
<Marker
key={place._id}
position={
{
lat: lat,
lng:lng
}
}
animation={2}
/>
)
})
this.setState({
coords: markers
})
})
}
render() {
return (
<div>
<Navbar />
<Map
google={this.props.google}
zoom={4}
>
{this.state.coords}
</Map>
</div>
)
}
}
const connectVaca = connect(state => ({vacations: state}), {getVacations})(GoogleMaps);
export default GoogleApiWrapper({
apiKey: "API KEY HERE"
})(connectVaca)
编辑:由于loadVacations
是重击,因此您需要将其传递给dispatch
。像这样更改传递给mapDispatchToProps
的{{1}}函数:
connect
Edit2 :它与以下事实有关:页面加载后,react运行初始const connectVaca = connect(
state => ({vacations: state}),
dispatch => {
return { getVacations: () => dispatch(getVacations()) }
}
)(GoogleMaps);
调用。然后,一旦安装了组件,就会调用render()
。在componentDidMount
中,运行异步函数componentDidMount
。由于您没有等待getVacations
中的API调用完成,因此标记创建过程尚未加载任何休假。每当您访问新标签页并返回到您的应用程序时,getVacations
就会再次发生,并显示以前的API调用中加载的休假。
尝试从您的操作render
返回承诺。然后,每当您在getVacations
中调用getVacations
时,请将componentDidMount
调用链接到then
。在getVacations
内应放置坐标创建和then
调用。然后,我相信您的代码会工作。
Promise.all
然后在您的export const getVacations = () => {
return dispatch => {
// returning axios.get will return a promise you can chain a then call on
return axios.get("/vacations").then(response => {
dispatch({
type: "GET_VACATIONS",
vacations: response.data
})
}).catch(err => {
console.log(err);
})
}
}
函数中:
componentDidMount