You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中使用map函数渲染MapView Marker时遇undefined问题

Fixing the Undefined Error When Rendering Markers in React Native Maps

Hey there, let's break down why you're seeing that undefined error when trying to render your markers, and fix it step by step. I noticed a few critical issues in your code that are causing this problem:

Key Issues in Your Code

  • Your map function doesn't return values
    In your componentDidMount when updating markers via setState, the map callback only modifies matching markers but doesn't return anything. This means the resulting array will be filled with undefined values, which causes errors when you try to access marker.latitude in the render method.

  • Incorrect watch ID retrieval
    The watchId isn't part of position.coords — it's the return value of navigator.geolocation.watchPosition() itself. Your current code is trying to get it from the wrong place, so id becomes NaN, and your code can never match existing markers.

  • Direct state access in async setState
    setState is asynchronous, so using this.state.markers directly inside it can lead to using stale state. You should use the functional update pattern to ensure you're working with the latest state.

Fixed Code

Here's the corrected version of your component with explanations of the changes:

import React, {Component} from 'react';
import {AppRegistry, Text, View, StyleSheet} from 'react-native'
import MapView from 'react-native-maps'

export default class myapp extends Component{
  constructor(props){
    super(props);
    this.state ={
      markers: [
        { watchId: 0, latitude:3, longitude:2 },
        { watchId: 2, latitude:3, longitude:2 }
      ],
      watchId: null // Store watchId to clean up later if needed
    }
  }

  componentDidMount(){
    // Get the correct watchId from the watchPosition return value
    const watchId = navigator.geolocation.watchPosition((position)=>{
      const lat = parseFloat(position.coords.latitude)
      const long = parseFloat(position.coords.longitude)
      
      // Use functional setState to access latest state
      this.setState(prevState => {
        let found = false;
        // Map returns updated markers or original ones
        const updatedMarkers = prevState.markers.map(marker =>{
          if(marker.watchId === watchId){
            found = true;
            // Return a new object instead of mutating the old one (immutable update)
            return {...marker, latitude: lat, longitude: long};
          }
          // Return unmodified marker to keep it in the array
          return marker;
        });

        if(!found){
          // Add new marker without replacing the entire array
          return {
            markers: [...updatedMarkers, {watchId: watchId, latitude: lat, longitude: long}]
          };
        }

        return { markers: updatedMarkers };
      });
    }, null, {timeout:0, distanceFilter:0});

    // Save watchId to state for potential cleanup (like in componentWillUnmount)
    this.setState({ watchId });
  }

  // Optional: Clean up geolocation watch when component unmounts
  componentWillUnmount() {
    if(this.state.watchId){
      navigator.geolocation.clearWatch(this.state.watchId);
    }
  }

  render(){
    return(
      <View>
        <MapView 
          style={{height:350,width:350,marginTop:300,alignSelf:'center'}}
          initialRegion={{
            latitude: 37.33,
            longitude: -121.4024,
            latitudeDelta: 0.0922,
            longitudeDelta: 0.0421,
          }}
          showsUserLocation={true}
          followsUserLocation={true}
          showsMyLocationButton={true}
        >
          {/* Add unique key prop to avoid React warnings */}
          {this.state.markers.map(marker =>{
            return(
              <MapView.Marker 
                key={marker.watchId}
                coordinate={{latitude:marker.latitude,longitude:marker.longitude}}
                title={"title"}
                description={"description ey"}
              />
            );
          })}
        </MapView>
      </View>
    );
  }
}

AppRegistry.registerComponent('myapp',()=>myapp);

Additional Notes

  1. Immutable Updates: Instead of mutating the original marker object, we return a new object with the updated coordinates. This helps React detect changes properly.
  2. Key Prop: Adding a key prop to each MapView.Marker prevents React from throwing list rendering warnings and improves performance.
  3. Cleanup: The componentWillUnmount method clears the geolocation watch to prevent memory leaks when the component is removed.

内容的提问来源于stack exchange,提问作者Parth Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:12:04