Search code examples
reactjsreact-nativereact-native-maps

How to open callouts for React Native Maps markers upon loading


I want all the callouts for all the markers to be opened upon mounting the screen component. Currently, it only opens only when it's clicked on the marker. How do I use useRef in a functional component to do this?

const markerRef = useRef(React.createRef)

return (
    <View style={styles.container}>
        <MapView 
            style={{ flex: 1 }} 
            region={region}
            onRegionChangeComplete={onRegionChangeComplete}
        >
            {data && data.posts.map(marker => (
                <Marker
                    ref={markerRef}
                    key={marker.id}
                    coordinate={{latitude: marker.latitude, longitude: marker.longitude }}    
                >
                    <Callout>
                        <Text>{marker.title}</Text>
                        <Text>{JSON.stringify(marker.price)}</Text>
                    </Callout>
                </Marker>
            ))}
        </MapView>
        <View style={styles.inputContainer}> 
            <Icon name="magnify" size={30} color="lightgrey" />
            <TextInput 
                placeholder="Search Term"
                style={styles.input}
                onChangeText={setSearch}
                value={search}
                returnKeyType="search"
                onSubmitEditing={handleSubmit}
            />
        </View>
    </View>

When I console.log(markerRef.current), it doesn't provide the showCallout() method.


Solution

  • The cleanest way is to create your own view as a marker. Arbitrary React Views as Markers

    You can see an example of the marker here. And here is an example of it used here.

    This is just a start. You could put your own click handler on the marker and hide it.

    So, this is probably less ideal, but might work as a hack. Start with a rendering function.

    renderCallout() {
        if(this.state.calloutIsRendered === true) return;
        this.setState({calloutIsRendered: true});
        this.markerRef.showCallout();
    }
    

    Then add it to the onRegionChangeComplete event.

    <MapView
      onRegionChangeComplete={() => this.renderCallout()}
      ...
    >