What is the possible reason of why react native MapView is lagging? - react-native

My app have structure like this,
MapPage.js that contain expo-barcode-scanner wrapped with Modal and MapView.
DetailsPage.js that contain search result/products' details.
User can use the barcode scanner or TextInput(also in MapPage, not wrapped in Modal) to search product ID and the app will navigate to DetailsPage for result. If result is not found, app will automatically navigate.goBack() to MapPage. If result existed, will goto the result and stay in DetailsPage.
User can also navigate to DetailsPage by pressing marker callout on MapView.
Here is situation:
user press on marker callout(navigate to DetailsPage), then press back(navigate.goBack()) to MapPage : No lagging
user search by TextInput, then back to MapPage: No lagging whether search result exist or not
user search by Barcode, result not exist, automatically back to MapPage: not lagging
user search by Barcode, result existed, stay in DetailsPage, user manually press back: LAGGING
Below codes for your references
//MapPage
<MapView
style={{ width: '100%', height: '100%' }}
provider={PROVIDER_GOOGLE}
showsMyLocationButton={true}
showsUserLocation={true}
region={{
latitude: region.latitude,
longitude: region.longitude,
latitudeDelta: region.latitudeDelta,
longitudeDelta: region.longitudeDelta,
}}>
<MapMarker
markerLocation={markers}
countryCode={country.countryCode}
/>
</MapView>
...
<TextInput
placeholder={
i18n.t('SearchId')
}
placeholderTextColor="white"
onSubmitEditing={() =>
handleBarCodeScanned({ data: textSearchData })
}
onChangeText={(text) => {
settextSearchData(text.toUpperCase());
}}
/>
<Pressable onPress={() => setqrcodeModalVisi(true)}>
<Ionicons
name="qr-code-outline"
size={33}
color="white"
/>
</Pressable>
...
<Modal
visible={qrcodeModalVisi}
animationType="slide"
onRequestClose={() => setqrcodeModalVisi(false)}
transparent={true}>
<View>
<Pressable onPress={() => setqrcodeModalVisi(false)}>
<Feather
name="x"
size={24}
color="white"
/>
</Pressable>
{!hasPermission && (
<View>
<Text
style={{
color: colors.text,
}}>
Camera access denied.
</Text>
<Pressable onPress={() => getBarCodeScannerPermissions()}>
<Text style={{ color: colors.secondary }}>
Goto setting page
</Text>
</Pressable>
</View>
)}
{hasPermission && (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}>
<BarCodeScanner
onBarCodeScanned={
scanned ? undefined : handleBarCodeScanned
}
style={{
width: '100%',
height: '80%',
}}
/>
</View>
)}
</View>
</Modal>
//MapMarker
<View>
{markerLocation.map((array) => (
<Marker
key={array.title}
coordinate={{
latitude: array.latitude,
longitude: array.longitude,
}}
image={require('../../../assets/icons/map_marker.png')}
title={''}
description={''}
onCalloutPress={() => handleMapMarkerPress(array.regionCode)}>
<Callout>
<View
style={{
backgroundColor: 'white',
width: 180,
paddingVertical: 5,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text
style={{
width: '80%',
textAlign: 'center',
color: colors.secondary,
fontWeight: 'bold',
}}>
{array.title}
</Text>
<View
style={{
backgroundColor: colors.secondary,
width: '80%',
height: 25,
alignItems: 'center',
justifyContent: 'center',
marginTop: 2,
flexDirection: 'row',
marginVertical: 5,
}}>
<Text style={{ color: 'white', fontWeight: 'bold' }}>
{i18n.t('MapMarkerBtn')}
</Text>
</View>
</View>
</Callout>
</Marker>
))}
</View>
Thanks!

Related

navigate screen overlaying with other screen

hello I am new to react native I am facing an abnormal behavior on navigation which happens between two modal screens first modal screen as shown in the picture on navigate it goes into next screen works fine
here is second modal picture on navigate
problem comes when I press on div upload cnic picture front and back then screens getting merged both are different component , previous screen modal appear as you seen in photo I marked in the screen with two modal screens
here is my CNIC upload screen code
<TouchableWithoutFeedback
onPress={() => {
displayModal(!modalVisible);
}}>
<View style={styles.container}>
<Modal
onBackdropPress={() => setModalVisible(false)}
onSwipeComplete={() => setModalVisible(false)}
swipeDirection={['down']}
useNativeDriverForBackdrop
style={{margin: 0}}
isVisible={modalVisible}>
<View
style={{
flex: 1,
borderTopLeftRadius: 25,
borderTopRightRadius: 25,
marginTop:
steper === 'step' ? deviceHeight * 0.1 : deviceHeight * 0.2,
backgroundColor: 'white',
alignItems: 'center',
}}>
<View
style={{
width: '100%',
height: '100%',
// alignItems: 'center',
marginTop: 3,
justifyContent: 'space-evenly',
}}>
<View style={{width: '100%', alignItems: 'center'}}>
<PopupBorder />
</View>
{/* first half */}
<View
style={{
width: '100%',
alignItems: 'center',
height: '18%',
justifyContent: 'flex-end',
}}>
<View style={styles.subContainer}>
<Image
style={{width: '40%', height: '50%', resizeMode: 'contain'}}
source={require('../assests/finger-print.png')}
/>
<Text style={{fontSize: 18}}>Verify your account </Text>
<SubTitle
amount
color="#636363"
title="We require CNIC and Selfie for the verification"
/>
</View>
</View>
{/* steper */}
<View
style={{
height: '10%',
justifyContent: 'center',
}}>
<DocumentSteper step={steper} />
</View>
{/* steper */}
{/* second half */}
<View
style={{
width: '100%',
height: '70%',
alignItems: 'center',
justifyContent: 'center',
}}>
<View style={styles.subContainer}>
<TouchableOpacity
style={{
width: '100%',
height: '80%',
alignItems: 'center',
}}>
{steper === 'step' ? (
<>
<TouchableOpacity
activeOpacity={0.6}
onPress={takeFrontPhotoFromCamera}
style={styles.imageContainer}>
<ImageBackground
style={styles.uploadStyle}
// resizeMode="contain"
source={
frontImage === null ? null : {uri: frontImage}
}>
<Image source={require('../assests/upload.png')} />
<View style={{paddingTop: 5}}>
<SubTitle
title="CNIC FRONT"
font
color="#06B2BC"
fontSize={14}
amount
/>
</View>
</ImageBackground>
</TouchableOpacity>
<TouchableOpacity
activeOpacity={1}
onPress={takeBackFrontPhotoFromCamera}
style={styles.imageContainer}>
<ImageBackground
style={styles.uploadStyle}
// resizeMode="contain"
source={
backImage === null ? null : {uri: backImage}
}>
<Image source={require('../assests/upload.png')} />
<View style={{paddingTop: 5}}>
<SubTitle
title="CNIC FRONT"
font
color="#06B2BC"
fontSize={14}
amount
/>
</View>
</ImageBackground>
</TouchableOpacity>
</>
) : (
<TouchableOpacity
onPress={takeSelfie}
style={styles.singleimageContainer}>
<ImageBackground
style={styles.uploadStyle}
// resizeMode="contain"
source={selfie === null ? null : {uri: selfie}}>
<Image source={require('../assests/upload.png')} />
<View style={{paddingTop: 5}}>
<SubTitle
title="CNIC FRONT"
font
color="#06B2BC"
fontSize={14}
amount
/>
</View>
</ImageBackground>
</TouchableOpacity>
)}
</TouchableOpacity>
<View
style={{
width: '100%',
height: '20%',
justifyContent: 'flex-end',
}}>
<Button
click={verify}
title={
steper === 'step' ? ' Verify CNIC' : 'Verify SELFIE'
}
backgroundColor="white"
marginBottom={15}
color="#06B2BC"
/>
</View>
</View>
</View>
</View>
</View>
</Modal>
<TouchableWithoutFeedback onPress={() => !modalVisible}>
<TouchableOpacity style={styles.map}>
<Image source={require('../assests/map.png')} />
</TouchableOpacity>
</TouchableWithoutFeedback>
</View>
</TouchableWithoutFeedback>
We can't see from your code sample where you are calling the second step "upload cnic picture". It seems that you are calling another modal on top of the first one.
If you have planned to have a full process within this modal, it is probably best to integrate a proper navigator rather than "navigate" between modals.

React native react-native-google-places-autocomplete VirtualizedLists warning

I created a form in which I have a field called address. Where I implemented 'react-native-google-places-autocomplete' plugin. It's working fine if I don't add scrollView. But I need to add scrollView just because I have so many input fields inside that form. but then I got a warning "VirtualizedLists should never be nested inside plain ScrollViews with the same orientation".
Here is my code:
Add.js
<SafeAreaView style={{ flex: 1, paddingTop: Platform.OS === "android" ? StatusBar.currentHeight : 0, backgroundColor: 'white' }}>
<View style={{ flex: 1 }}>
<ScrollView scrollEventThrottle={16}>
<View style={{ flex: 1 }}>
<Text style={{ fontSize: 20, marginTop: 5, marginBottom: 10, paddingHorizontal: 15, fontFamily: 'Mulish-SemiBold' }}>Add Ground</Text>
<TouchableWithoutFeedback style={styles.button} onPress={(e) => this.chooseFile()}>
<Image source={this.state.avatarSource ? this.state.avatarSource : require('./../../assets/images/default-cover.jpg')} style={{ width: '100%', height: 150 }} />
</TouchableWithoutFeedback>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Name</Text>
<TextInput
style={styles.input}
placeholder="e.g Drealit Stadium"
onChangeText={name => this.setState({ name })}
value={this.state.name}
autoCorrect={false}
/>
</View>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Address</Text>
{/*
onChangeText={address => this.setState({ address })}
value={this.state.address}
*/}
<ScrollView>
<GooglePlacesInput />
</ScrollView>
</View>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Contact Person Name</Text>
<TextInput
style={styles.input}
placeholder="e.g David Johnson"
onChangeText={organizer_name => this.setState({ organizer_name })}
value={this.state.organizer_name}
autoCorrect={false}
/>
</View>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Contact Person Number</Text>
<TextInputMask
type={'cel-phone'}
options={{
maskType: 'INTERNATIONAL',
}}
placeholder="e.g 509-962-9014"
style={styles.input}
value={this.state.organizer_number}
onChangeText={organizer_number => this.setState({ organizer_number })}
/>
</View>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Description</Text>
<TextInput
placeholder="e.g A Ground suitable for small side cricket tournament. Ideal for some fast paced cricket and lot of fun."
onChangeText={description => this.setState({ description })}
value={this.state.description}
autoCorrect={false}
multiline={true}
numberOfLines={4}
style={[styles.input, { height: 'auto', textAlignVertical: 'top' }]}
/>
</View>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Rate per hour / day</Text>
<TextInput
style={styles.input}
placeholder="e.g 3500"
keyboardType="numeric"
onChangeText={ratePerHourDay => this.setState({ ratePerHourDay })}
value={this.state.ratePerHourDay}
autoCorrect={false}
/>
</View>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Rate per hour / night</Text>
<TextInput
style={styles.input}
placeholder="e.g 4500"
keyboardType="numeric"
onChangeText={ratePerHourNight => this.setState({ ratePerHourNight })}
value={this.state.ratePerHourNight}
autoCorrect={false}
/>
</View>
<View style={{ marginHorizontal: 15, marginVertical: 10 }}>
<TouchableWithoutFeedback style={styles.button} onPress={(e) => this.manageAddGround(e)}>
<LinearGradient
colors={["#4678f6", "#4475ee", "#5053eb"]}
start={{ x: 0, y: 0 }}
end={{ x: 0, y: 0 }}
locations={[0, 0.5, 0.6]}
style={styles.appButtonContainer}
>
<Text style={styles.buttonText}>Save</Text>
</LinearGradient>
</TouchableWithoutFeedback>
</View>
</View>
</ScrollView>
</View>
</SafeAreaView>
GooglePlacesInput.js
<View style={{ flex: 1 }}>
<GooglePlacesAutocomplete
placeholder='e.g 640 Cross Creek Dr, Ellensburg, WA, 98926'
query={{
key: GOOGLE_PLACES_API_KEY,
language: 'en',
}}
enablePoweredByContainer={false}
onPress={(data, details = null) => {
console.log("GooglePlacesInput -> data", data)
}}
debounce={200}
styles={{
textInputContainer: {
backgroundColor: '#fff',
borderTopWidth: 0,
borderBottomWidth: 0,
},
textInput: {
marginLeft: 0,
marginRight: 0,
height: 40,
borderBottomWidth: 1,
color: '#000',
borderBottomColor: '#dedede'
},
predefinedPlacesDescription: {
color: '#1faadb',
},
listView: {
backgroundColor: '#fff',
borderWidth: 0.5,
borderColor: '#dedede',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 6,
},
shadowOpacity: 0.05,
shadowRadius: 10,
elevation: 4
}
}}
/>
</View>
You are receiving this warning because react-native-google-places-autocomplete renders a component to show results, and you have wrapped in a .
It's a warning, not an error. If it works for you can leave it as is.

First show the profile clicked then swipe between profiles react native

Hi how can I first show the user that I've clicked on and then display a swiper ? I can't find a logic for that. I have a list of users and when I click on one, it should open a new component where we will find more infos about that user. Then I want to swipe between the list of users on the same component of the description ?
Here are my user profile component and the flatlist :
render () {
var colorConnected;
if (this.props.navigation.getParam('Statut') === "ON") {
colorConnected = "#1fbc26";
}
else if (this.props.navigation.getParam('Statut') === "OFF") {
colorConnected = "#ff0303";
}
else {
colorConnected = "#ffd200";
}
return (
<Swiper showsPagination={false}>
{this.state.items.map((item, key) => {
return (
<ScrollView style = {styles.view_container}>
<View style={styles.photo}>
<ImageBackground source={{uri:this.props.navigation.getParam('Photo')}} style={{ width: '100%', height: '100%' }}>
<View style={styles.photo_content}>
<LinearGradient colors={['transparent', 'rgba(0,0,0,0.5)']} style={{ position: 'absolute', left: 0, right: 0, bottom: 0, height: 80 }} />
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<View>
<Text style={{ fontSize: 40, color:'white' }}>{this.props.navigation.getParam('Age')}</Text>
</View>
<View style={{ marginRight: 7, marginLeft: 7, backgroundColor: '#ffffff', width: 1, height: 39 }}></View>
<View style={{ flexDirection: 'column', flex:1 }}>
<View style={{ flexDirection: 'row' }}>
<View style={[styles.bulle_presence, { backgroundColor: colorConnected } ]}></View>
<Text style={{ fontSize: 18, fontWeight: '600', color:'white' }}>{this.props.navigation.getParam('Pseudo')}</Text>
</View>
<View style={{ flexDirection: 'row', justifyContent: 'space-between'}}>
<Text style={{ fontSize: 15, color:'white' }}>{this.props.navigation.getParam('Distance')}</Text>
<Text style={{ fontSize: 15, color:'white'}}>{this.props.navigation.getParam('Genre')}</Text>
</View>
</View>
</View>
</View>
</ImageBackgroud>
</View>
</ScrollView>
)
})}
</Swiper>
)}
}
render() {
GLOBAL.data = this.state.dataSource;
//console.log(GLOBAL.data);
return (
<SafeAreaView style={{ flex:1 }}>
<View style={styles.main_container}>
<FlatList style={styles.flatList}
data={this.state.dataSource}
extraData = {this.state}
keyExtractor={(item, index) => item.MembreId}
renderItem={(item) => <UserItem user={item} displayDetailForUser={this._displayDetailForUser} />}
numColumns={numColumns}
refreshing={this.state.refreshing}
onRefresh={this.handleRefresh} />
</View>
</SafeAreaView>
)
}
With this code, I'm only able to swipe on the user where I've clicked. The others user are not showing.
You can open a modal then use a carousel like react-native-snap-carousel in full screen mode to generate your use case

react native Modal opening from last object in array

I am creating a render method where it displays information from a state array, and I want it so that when a user touches a Card a Modal will open presenting the same information.
My code is as follows:
this.state = {
fontLoaded: false,
feed: [{
username: ["Jeff", "Kyle", "David"],
caption: ["Great", "Amazing", "Not so Good"],
comments: ["Comment 1", "Comment 2", "No Comment"],
photo:[Pic1,Pic2,Pic3],
}]
}
state = {
isModalVisible: false,
};
toggleModal = () => {
this.setState({ isModalVisible: !this.state.isModalVisible });
};
renderFeed = () => {
return this.state.feed.map((card, index) => {
return card.username.map((username, i) => {
if(card.caption[i])
return (
<View>
<TouchableHighlight onPress={this.toggleModal} underlayColor="white">
<Card
key={`${i}_${index}`}
image={card.photo[i]}
containerStyle={{borderRadius:10, marginRight:1, marginLeft:1,}}>
<View
style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between' }}
>
<View style={{ flexDirection: 'row'}}>
<Avatar
size="small"
rounded
source={card.photo[i]}
/>
</View>
<View style={{flexDirection:'row'}}>
<Avatar
rounded
icon={{ name:'heart-multiple-outline', type:'material-community', color: '#ff4284'}}
overlayContainerStyle={{marginLeft:5}}
reverse
size='small'/>
<Avatar
reverse
rounded
icon={{ name:'comment-processing-outline', type:'material-community' }}
overlayContainerStyle={{backgroundColor: '#dbdbdb',marginLeft:5}}
size='small'/>
</View>
</View>
{ this.state.fontLoaded == true ? (
<View style={{flexDirection:'row'}}>
<Text style={{fontFamily: 'MontserratB', color:'#bf00b9', marginTop:10}}>{username}</Text>
<Text style={{fontFamily:'Montserrat', marginTop:10}}>{card.caption[i]}</Text>
</View>
) : (<Text> Loading...</Text>)
}
<Text style={{marginTop:4, color:'#878787'}}>{card.comments[i]}</Text>
</Card>
</TouchableHighlight>
<Modal
animationIn="zoomInDown"
animationOut="zoomOutDown"
animationInTiming={700}
animationOutTiming={600}
backdropTransitionInTiming={600}
backdropTransitionOutTiming={600}
isVisible={this.state.isModalVisible}>
<Image source={card.photo[i]}
style={{width: SCREEN_WIDTH - 20,
height: 300, justifyContent: 'center', alignSelf:
'center' }}/>
<Card
containerStyle={{ width: SCREEN_WIDTH - 20, marginTop: 0, justifyContent: 'center', alignSelf:
'center' }}>
<View style={{ flexDirection:'row' }}>
<Avatar
size="small"
rounded
source={card.photo[i]}
/>
<View style={{ flex:2, flexDirection:'row', justifyContent:'flex-end' }}>
<Avatar
rounded
icon={{ name:'heart-multiple-outline', type:'material-community'}}
overlayContainerStyle={{backgroundColor: '#ff4284',marginLeft:5}}
reverse
size='small'/>
<Avatar
reverse
rounded
icon={{ name:'comment-processing-outline', type:'material-community' }}
overlayContainerStyle={{backgroundColor: '#dbdbdb',marginLeft:5}}
size='small'/>
</View>
</View>
<View style={{ flexDirection:'row' }}>
<Text style={{fontFamily: 'MontserratB', color:'#bf00b9', marginTop:10}}>{username}</Text>
<Text style={{fontFamily:'Montserrat', marginTop:10}}>{card.caption[i]}</Text>
</View>
<Text style={{marginTop:4, color:'#878787'}}>{card.comments[i]}</Text>
</Card>
<Button style={{marginTop:0, borderBottomRightRadius: 20, borderBottomLeftRadius: 20, borderTopLeftRadius: 0, borderTopRightRadius: 0, width: SCREEN_WIDTH - 20, alignSelf: 'center', justifyContent: 'center'}} title="Close" onPress={this.toggleModal} />
</Modal>
</View>
);
return <React.Fragment />;
});
})
}
everything works perfectly except that no matter which Card is touched a Modal is opened presenting the last objects in the array. So no matter which of the three cards are pressed, a Modal will always open with the information regarding David
Modified snack version of your sample:
https://snack.expo.io/H1yHPQQdr

Place a component to middle right in React Native

I am still learning about react native especially flexbox. So I have a TouchableOpacity that have some child components on it, like this:
And the problem is I can't move that arrow icon to the middle right of TouchableOpacity. I try with
justifyContent: 'center', alignItems: 'flex-end' But nothing happened. Here is my code :
<TouchableOpacity onPress={this.onRowPress}>
<View style={{ padding: 5 }}>
<CardSection style={{ flex: 1 }}>
<Icons name="monitor" size={50} style={{ paddingLeft: 10 }} />
<View style={{ flexDirection: 'column' }}>
<Text style={styles.channelStyle}>
{item.nama}
</Text>
<Text
style={
[item.status === 'Online' ? onlineTextStyle : offlineTextStyle]
}
>
{item.status}
</Text>
</View>
<Icons name="arrow-right" size={50} style={styles.arrowIconStyle} />
</CardSection>
</View>
</TouchableOpacity>
And this is the style:
const styles = {
channelStyle: {
fontSize: 25,
paddingLeft: 30
},
onlineTextStyle: {
paddingLeft: 30,
color: 'green'
},
offlineTextStyle: {
paddingLeft: 30,
color: 'red'
},
footerTextStyle: {
flex: 1,
textAlign: 'center',
color: '#fff',
padding: 5,
fontSize: 18
},
arrowIconStyle: {
justifyContent: 'center',
alignItems: 'flex-end'
}
};
Is there something I missed?
Could you try the following and let me know how it goes?
// 1. Add flexDirection row here.
<CardSection style={{ flex: 1, flexDirection: 'row' }}>
...code...
// 2. Add alignSelf here.
<Icons name="arrow-right" size={50} style={[styles.arrowIconStyle, {alignSelf: 'flex-end'}]} />
</CardSection>
If that doesn't work, try not doing the previous step 2 and instead try this.
...code...
<Icons name="arrow-right" size={50} style={styles.arrowIconStyle} />
const styles = {
...code...
arrowIconStyle: {
justifyContent: 'center',
alignSelf: 'flex-end'
}
};
Update
<TouchableOpacity onPress={this.onRowPress}>
<View style={{ padding: 5 }}>
<CardSection style={{flex: 1, flexDirection: 'row', justifyContent: 'space-between'}}>
<View style={{ flex: 1 }}>
<Icons name="monitor" size={50} style={{ paddingLeft: 10 }} />
<View style={{ flexDirection: 'column' }}>
<Text style={styles.channelStyle}>
{item.nama}
</Text>
<Text
style={[item.status === 'Online' ? onlineTextStyle : offlineTextStyle]}>
{item.status}
</Text>
</View>
</View>
<Icons name="arrow-right" size={50} style={styles.arrowIconStyle} />
</CardSection>
</View>
</TouchableOpacity>