Nathan Davey
Nathan Davey

Reputation: 11

React-Native-Maps Marker Array in Child Component

I'm currently learning react-native and react-native-maps (using typescript ES6) and I'm having some issues rendering markers in that they just don't appear. I've attempted to separate my logic into components that make's sense to me but I'm wondering if this is the reason I can't get them to render.

What I have is the following:

Main Map Component

<MapView style={styles.map}
         region={this.props.region}
         showsUserLocation={true}
         followsUserLocation={false}>
    <View>
        <SearchCircle />
        <MarkerList />
    <View>
 <MapView>

SearchCircle

The SearchCircle works perfectly and the code contains:

import { Circle } from 'react-native-maps';

...

class SearchCircle extends React.Component<SearchProps> {
    render() {
        return (
            <Circle center={this.props.user.location}
                    radius={this.props.map.searchRadius}
                    fillColor={'rgba(230,238,255,0.5)'}
                    strokeColor={'#1A66FF'}
                    strokeWidth={1} />
        );
    }
}

MarkerList - ISSUE

The MarkerList is the component that does not render correctly. It contains:

class MarkerList extends React.Component<MarkerListProps> {

    // render our contacts
    render() {
        return (
            <View>
                {this.props.markerlist[0] != undefined && this.props.markerList.map((marker, index) => (
                    this.renderMarker( marker, index )
                ))}
            </View>
        );
    }

    renderMarker( marker: MarkerEntry, index: number ) {
        return (
            <View key={index}>
                <Marker coordinate={marker.location} title={marker.title} />
                <Text>{'Lat: ' + marker.location.latitude + ', Long: ' + marker.location.longitude}</Text>
            </View>
        );
    }
}

The MarkerList component does call render() when the state updates (when I update the markers locations) BUT only the Text element renders/updates correctly. The Lat/Lng is displayed correctly on my screen however the Marker element does not appear at all. The markerlist property for the MarkerList component is a list of type MarkerEntry which contains the following:

interface MarkerEntry {
    title: string
    location: LatLng
} 

No matter what I try, I cannot get any markers to render from this array. If I statically define markers then everything works just fine but with my property array list map they never render.

Static Example that works

class MarkerList extends React.Component<MarkerListProps> {

    // render our contacts
    render() {

        let marker = {
            id: 'Test',
            location: {
                latitude: -31.970097415447232,
                longitude: 115.92362245895334
            }
        };

        let markerArray: any[] = [];
        markerArray.push( marker );

        return (
            <View>
                {markerArray[0] != undefined && markerArray.map((c, index) => (
                    <Marker key={index} coordinate={c.location} title={c.id} />
                ))}
            </View>
        );
    }
}

Is anyone able to assist. I can't understand what I'm doing wrong or if I'm missing something about how react-native should be structured for this to work.

Thanks in advance!

Upvotes: 0

Views: 1451

Answers (1)

Nathan Davey
Nathan Davey

Reputation: 11

So I've managed to solve my problem and thought I'd leave my final solution here for anyone else that needs it. The issues were with how I was defining the MapView and also with how I was returning the map results.

Map Component

For the main map component I had to remove the child <View> entry I had defined.

Before

<MapView style={styles.map}
         region={this.props.region}
         showsUserLocation={true}
         followsUserLocation={false}>
    <View>**
        <SearchCircle />
        <MarkerList />
    <View>
 <MapView>

After

<MapView style={styles.map}
         region={this.props.region}
         showsUserLocation={true}
         followsUserLocation={false}>
    <SearchCircle />
    <MarkerList />
 <MapView>

MarkerList

The second part I had to change was the render function and it's syntax in the render function.

Before

class MarkerList extends React.Component<MarkerListProps> {
    // render our contacts
    render() {
        return (
            <View>
                {this.props.markerlist[0] != undefined && this.props.markerList.map((marker, index) => (
                    this.renderMarker( marker, index )
                ))}
            </View>
        );
    }

    renderMarker( marker: MarkerEntry, index: number ) {
        return (
            <View key={index}>
                <Marker coordinate={marker.location} title={marker.title} />
                <Text>{'Lat: ' + marker.location.latitude + ', Long: ' + marker.location.longitude}</Text>
            </View>
        );
    }
}

After

Note the additional return statements outside and inside the map call and the removal of the <View> element.

class MarkerList extends React.Component<MarkerListProps> {
    // render our contacts
    render() {
        return this.props.markerList.map((marker, index) => {
            return( this.renderMarker( marker, index ));
        });
    }

    renderMarker( marker: MarkerEntry index: number)  {
        return (
            <View key={index}>
                <Marker coordinate={marker.location} title={marker.title} />
            </View>
        );
    }
}

Upvotes: 1

Related Questions