Mapbox React Native can't access the map's methods - react-native

This is probably basic, but I'm getting tripped up with the documentation between the JS Mapbox and the React Native Mapbox. I'm creating a new map instance by importing mapbox into my project via import Mapbox from '#mapbox/react-native-mapbox-gl';
and then in the render() function I'm loading the map via:
<View style={container}>
<Mapbox.MapView
styleURL={Mapbox.StyleURL.Light}
zoomLevel={12}
centerCoordinate={[lat, lng]}
style={styles.container}
showUserLocation
>
{this.renderAnnotations()}
</Mapbox.MapView>
</View>
The renderAnnotations() function I've defined as follows:
renderAnnotations() {
return this.state.stations.map((station, index) =>
<TouchableHighlight onPress={this._map.flyTo.bind(this, station)} key={index}>
<View ref={component => this._root = component}>
<StationPoint key={station.id} station={station} />
</View>
</TouchableHighlight>
);
}
The goal is for it to render points on the map with a corresponding flyTo onPress event. The map and these points render perfectly fine, but the onpress event returns:
error "Cannot read property 'flyTo' of undefined"
On this tutorial, it suggests you can access the map using this._map. Is this correct and I'm making a different error? Or is there an alternative way for accessing the map methods? Any help is much appreciated!

Figured out the answer, in case it helps someone else. I wasn't defining a ref property on the MapView. It should have had a reference defined as this._map like the following:
<View style={container}>
<Mapbox.MapView
ref={(c) => this._map = c}
styleURL={Mapbox.StyleURL.Light}
zoomLevel={12}
centerCoordinate={[lat, lng]}
style={styles.container}
showUserLocation
>
{this.renderAnnotations()}
</Mapbox.MapView>
</View>

Related

React native List footer component not rendering(funtion component)

I am trying to achieve pagination for infinite scrolling in react native. When loading, I want to render the loading spinner at the bottom of the Flat list component. (Note: I'm using Expo for this app)
const renderFooter = () => {
if (!category.loading) return null;
return (
<View style={spinnerStyles.container}>
<ActivityIndicator animating size="large" color="#0000ff" />
</View>
);
};
return (
<View style={styles.container}>
<FlatList
columnWrapperStyle={{ justifyContent: "space-between" }}
numColumns={2}
data={category.data}
renderItem={categoryItem}
keyExtractor={(item) => item._id + item.sub_category}
onEndReachedThreshold={0}
listFooterComponent={renderFooter}
onEndReached={() => loadMore()}
/>
</View>
);
The loading spinner not correctly working with the flat list footer.
Has anyone run into this issue before, or does anyone have a solution?
Sorry, it's my simple syntax error. It's actually ListFooterComponent not listFooterComponent. Now it's working fine, Thank you.
Instead of calling the refrence, call the function. It should look something like this.
ListFooterComponent={renderFooter()}

Im trying to do bottomSheet on react native but ım getting an error. Error is: Type 'string' is not assignable to type 'Ref<unknown> | undefined'

<BottomSheet
bottomSheerColor="#FFFFFF"
ref="BottomSheet"
initialPosition={'50%'}
snapPoints={['50%', '100%']}
isBackDrop={true}
isBackDropDismissByPress={true}
backDropColor="red" //======> this prop will change color of backdrop
header={
<View>
<Text style={styles.text}>Header</Text>
</View>
}
body={
<View style={styles.body}>
<Text style={styles.text}>Body</Text>
</View>
}
/>
the problem line is: ref="BottomSheet"
this ref is main problem
how can i fix this ?
String refs are legacy implementation. Please use the useRef hook to manage ref.
const bottomsheetRef = React.useRef(null)
....
<BottomSheet
ref={bottomsheetRef}
/>
Now to access the ref, do
bottomsheetRef.current

TouchableHighlight not working although using the source code from official react native documentation

I'm a new react native developer and I have an issue with TouchableHighlight where it always shows an error "Error: React.Children.only expected to receive a single React element child." in addition while I remove it is work as usual and I assume if this issue come from my device/vscode/browser. Because I already follow the source code from https://reactnative.dev/docs/touchablehighlight but still show that error.
Error image
Image without TouchableHighlight tag
Here my code
render() {
return (
<View style={styles.container}>
<TouchableHighlight onPress={this.onPress}>
<View style={styles.button}>
<Text>Touch Here</Text>
</View>
</TouchableHighlight>
<View style={[styles.countContainer]}>
<Text style={[styles.countText]}>
{this.state.count ? this.state.count : null}
</Text>
</View>
</View>
);}
From the error message, the issue might happen if you pass Mutlipe child components to TouchableHighlight
From the docs:
TouchableHighlight must have one child (not zero or more than one). If you wish to have several child components, wrap them in a View
<TouchableHighlight onPress={onPress}>
<View style={styles.button}> // Mutlipe child components are wrapped in a View
<Text>Touch</Text> // component 1
<Text>Here</Text> // component 2
</View>
</TouchableHighlight>

React Native, Passing Navigation to Stateless Flatlist component

Currently I have:
return(
<View style={{flex: 1, paddingTop:20}}>
<FlatList
data={this.state.dataSource}
renderItem={(data) => <EventCard eventinfo = {data.item} navigation=
{this.props.navigation}/>}
keyExtractor={(item) => item.eventname}
/>
and
const EventCard = ({eventinfo, navigation}) => {
return (
<TouchableOpacity style={{backgroundColor: 'transparent'}} onPress= {()
=> navigation.navigate('CurrRes')}>
I dont understand why Navigation cant be evaluated in my Eventcard, and navigation doesnt work. Any help would be appreciated.
(yes withnavigation is imported in the first file and the project runs but crashes when one of the flatlist items is pressed)
The error i get is
undefined is not an object (evaluating 'navigation.navigate')
Here is an example I found to explain it better.
You need to access props differently than just a normal function with deconstruction.
const Child = (props) => {
return (
<div style={{backgroundColor: props.eyeColor}} />
)
}
https://medium.com/#PhilipAndrews/react-how-to-access-props-in-a-functional-component-6bd4200b9e0b
Nevermind, I had to export the actual list with navigation so each of its nested stateless components could navigate. Sorry!

React Native detect tap on View

I’m writing a React Native app and I want to detect tap/clicks anywhere on the screen so I put an onClick handler on my <View> element but it doesn’t seem to be working. Here is my render function:
<View style={styles.container} onClick={this.onClick}>
<Text style={styles.welcome}>
Tap to change the background
</Text>
</View>
What do I need to do?
For making any element to handle touch/click events in a React-Native UI, you need to put the element inside a TouchableOpacity, TouchableWithoutFeedback, TouchableNativeFeedback or TouchableHighlight element:
<TouchableHighlight onPress = { this.onClick }>
<View style={styles.container}>
<Text style={styles.welcome}>
Tap to change the background
</Text>
</View>
</TouchableHighlight>
Hope that helps.
In React Native version > 55.3 you make check onPress events into your View if use onStartShouldSetResponder props.
Like example:
<View
style={{ flex: 1 }}
onStartShouldSetResponder={() => console.log('You click by View')}
>
<ScrollView
refreshControl={
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={this.onRefresh} />
}
>
<Text>Awesome</Text>
</ScrollView>
</View>
In example I showed how you can get onPress event on View and not blocking other event behind them. Refresh control still work correct.
In my case the following works fine. You can use onTouchStart and onTouchEnd handlers on any View via props, for example:
<View onTouchStart={() => this.doSomething()} />
More information
This worked for me...
onTouchEnd={() => alert('TAPPED')}
The easiest way to do that:
<TouchableOpacity style={styles.container} onPress={()=> whateverFunc(parameter)}>
<Text style={styles.welcome}>
Tap to change the background
</Text>
</TouchableOpacity>
So, you need to replace the 'View' component to a 'TouchableOpacity' or any other Touchable component and you also need to replace the 'onClick' prop to 'onPress'. That's all. The wrapping of a view with a TouchableWhatever component is not necessary at all.