开发者问题收集

React native 获取多标记 [未处理的承诺拒绝:TypeError:TypeError:未定义不是对象(评估'this.state.markers.map

2018-04-09
1506

我尝试从 Google Places (nearbysearch) API 获取数据,并根据我所做的查询返回 JSON 格式的位置列表对象。我只想处理这些对象并获取它们的纬度和经度值,然后将它们标记为要在 MapView 中呈现和返回的标记,这就是我目前所做的。 (请原谅我的代码混乱,因为这是我第一次尝试这样做并第一次尝试这些事情)。

export default class Whereto extends Component<{}> {

constructor(props) {
    super(props);

this.state = {
    latitude: null,
    longitude: null,
    location: null,
    error: null,
    markers:[
        {latlng: {latitude: null, longitude: null}}
    ]
};
}

然后我使用地理位置库查找我当前的位置,稍后将其用作对 vicinityplaces API 的查询

componentDidMount() {
        navigator.geolocation.getCurrentPosition(
            (position) => {
                this.setState({
                    latitude: position.coords.latitude,
                    longitude: position.coords.longitude,
                    error: null,
                });

            var myApiKey = '';

            fetch('https://maps.googleapis.com/maps/api/geocode/json?address=' + position.coords.latitude + ',' + position.coords.longitude + '&key=' + myApiKey)
                .then((response) => response.json())
                .then((responseJson) => {
                    //console.log('ADDRESS GEOCODE is BACK!! => ' + JSON.stringify(responseJson));
                   .... .....
                }) this section is not the complete code but it is working which is simply used to return my current location

在我的 componentdidMount() 函数下继续获取 Google Places vicinitysearch(API)

var apiPlaceskey = '';
                //https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=-33.8670522,151.1957362&radius=500&type=restaurant&keyword=cruise&key=YOUR_API_KEY



fetch('https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=' + position.coords.latitude + ',' + position.coords.longitude + '&radius=500&type=bus_station&key=' + apiPlaceskey)
                .then((respplaces) => respplaces.json())
                .then((responseJson2) => {
                    //console.log(JSON.stringify(responseJson2));
                    //var locationName = responseJson.results[0].address_components.filter(x => x.types.filter(t => t === 'administrative_area_level_2').length > 0)[0].short_name;
                    for (var i = 0, length = responseJson2.length; i < length; i++){
                        var data = json[i],
                           latlng = (responseJson2.results[0].geometry.location.lat, responseJson2.results[0].geometry.location.lng);
                    }
                this.setState({
                    markers: latlng
                })

看来 API 调用成功了,因为我确实得到了返回,这里有一个示例..

{
  "html_attributions": [],
  "results": [
    {
      "geometry": {
        "location": {
          "lat": 52.90050499999999,
          "lng": -1.478267
        },
        "viewport": {
          "northeast": {
            "lat": 52.90185398029149,
            "lng": -1.476918019708498
          },
          "southwest": {
            "lat": 52.89915601970849,
            "lng": -1.479615980291502
          }
        }
      },
      "icon": "https://maps.gstatic.com/mapfiles/place_api/icons/bus-71.png",
      "id": "4e992af207c8ff3503999574d25155ccf9b48f70",
      "name": "Randolph Road",
      "place_id": "ChIJM0syu93weUgRXSKhX6Flay8",
      "reference": "CmRRAAAAaE7cMbH9gq0w1U18RFtzX1GsEjTb7G2msTt4sL1hnvb5DrwTpFyznlVc9TvlfkOSkmJwU-dMa_RAvTO_8hCe_FeGIpQjwxMs7izIMg_oWYtGyzu9jQ0aIL9a_dRO40KvEhCrcpisZYRNNpDJH6p31oa6GhQpwF8PSkltIQvmsLMabEAnJWQ3OA",
      "scope": "GOOGLE",
      "types": [
        "bus_station",
        "transit_station",
        "point_of_interest",
        "establishment"
      ],
      "vicinity": "United Kingdom"
    },
    {
      "geometry": {
        "location": {
          "lat": 52.900963,
          "lng": -1.478217
        },
        "view ........
and here comes my render section.

render(){

        return(
            <View style={styles.container}>
                <Mainlogo/>

                <MapView style={styles.map}>

                    <MapView.Marker
                        coordinate={{
                            latitude: this.state.latitude,
                            longitude: this.state.longitude,
                            latitudeDelta: 0.02,
                            longitudeDelta: 0.02
                        }}
                        image={require('../img/my-pin-512.png')}
                        title={'you are here'}
                    />

                    {this.state.markers.map(marker => (
                        <MapView.Marker
                            coordinate={marker.latlng}
                        />

                    ))}

                </MapView>
            </View>
        )
    }
}

经过多次调整、修改和在网络上搜索后,我没有运气,并且继续收到此错误:

[Unhandled promise rejection: TypeError: TypeError: undefined is not an object (evaluating 'this.state.markers.map')] 22:23:24 ▼Warning: Failed prop type: The prop coordinate.latitude is marked as required in MapMarker, but its value is null.

在此处输入图片说明

在此处输入图片说明

新的错误

2个回答

我认为这就是您要尝试做的...创建一个带有纬度/经度的新数组并将其设置为标记。用以下内容替换您的循环和 setState:

const markers = responseJson2.results.map((result) => ({
  latlng: {
    latitude: result.geometry.location.lat,
    longitude: result.geometry.location.lng,
  }
});

this.setState({ markers });
Matt Aft
2018-04-10

乍一看,这看起来像是一个异步问题。

您的 render 方法没有检查未定义的值。 这是我正在谈论的部分:

{this.state.markers.map(marker => (
  // ...
))}

在您的获取请求获得结果之前,将调用 render 方法。但是到那时 this.state.markers 还不会被填充。

您应该添加某种占位符视图,可以在 google api 返回结果之前显示。

像这样:

render() {
  if (myContrivedCondition) return <View styles={styles.placeholder}/>;

  // your render code
}

响应到达后,它将由于您的 this.setState 触发组件更新。

希望这有帮助。

flaky
2018-04-10