i have a problem with passing params to a route in react native navigation. `route.params` is undefined sorry am abit new to react native - react-native

Here is my homepage. and i was to navigate to the bookings page while passing a uuid as a param to the bookings page.
import React from "react";
import {
Text,
View,
StatusBar,
ActivityIndicator,
StyleSheet,
SafeAreaView,
TextInput,
TouchableOpacity,
} from "react-native";
import { useFocusEffect } from "#react-navigation/native";
import APIKit from "../config/api/APIKit";
import Icon from "react-native-vector-icons/Feather";
import Card from "../components/Card";
import { ScrollView } from "react-native-gesture-handler";
function HomeScreen({ navigation }) {
const [loading, setLoading] = React.useState(true);
const [items, setItems] = React.useState([]);
const [limit, setLimit] = React.useState(7);
const image = require("../assets/pic1.jpg");
useFocusEffect(
React.useCallback(() => {
getData();
return () => {
setItems([]);
setLimit(9);
};
}, [])
);
const getData = () => {
setLoading(true);
APIKit.get(`items/?limit=${limit}&offset=1`)
.then((res) => {
console.log(res.data);
setLimit(limit + 6);
setItems([items, ...res.data.results]);
setLoading(false);
})
.catch((e) => console.log(e.request.response));
};
return (
<SafeAreaView
style={{ alignItems: "flex-start", justifyContent: "center" }}
>
<StatusBar style="auto" />
<View style={{ padding: 8 }}>
<View
style={{
flexDirection: "row",
alignItems: "center",
width: "100%",
marginTop: 5,
}}
>
<TextInput
placeholder={"Enter Item Name"}
style={{
flex: 1,
backgroundColor: "white",
height: 40,
borderColor: "black",
borderWidth: 1,
borderRadius: 5,
margin: 2,
paddingLeft: 8,
}}
/>
<TouchableOpacity
style={{
alignItems: "center",
alignSelf: "center",
borderWidth: 1,
width: 50,
borderRadius: 500,
}}
>
<Icon name="search" size={25} />
</TouchableOpacity>
</View>
<View style={{ flex: 1, marginTop: 20 }}>
<ScrollView>
<View
style={{
flex: 1,
flexDirection: "row",
flexWrap: "wrap",
justifyContent: "flex-start",
}}
>
{items !== []
? items.map((item, key) => {
return (
<Card
key={key}
name={item.item_name}
description={item.description}
onHandlePress={() =>
navigation.navigate("payment-options", {
uuid: item.uuid,
price: item.cost,
})
}
image={image}
/>
);
})
: null}
</View>
<TouchableOpacity
activeOpacity={0.9}
onPress={getData}
//On Click of button load more data
style={styles.loadMoreBtn}
>
<Text style={styles.btnText}>Load More</Text>
{loading ? (
<ActivityIndicator color="white" style={{ marginLeft: 8 }} />
) : null}
</TouchableOpacity>
</ScrollView>
</View>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
footer: {
padding: 10,
justifyContent: "center",
alignItems: "center",
flexDirection: "row",
},
loadMoreBtn: {
padding: 10,
width: 350,
marginHorizontal: 20,
alignSelf: "center",
backgroundColor: "#01ab9d",
borderRadius: 4,
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
},
btnText: {
color: "white",
fontSize: 15,
textAlign: "center",
},
});
export default HomeScreen;
and the booking page looks like this
import { Text, View, StatusBar, SafeAreaView, StyleSheet } from "react-native";
import { Button } from "react-native-elements";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
function PaymentOptionScreen(props) {
return (
<SafeAreaView
style={{ flex: 1, alignItems: "center", justifyContent: "center" }}
>
<StatusBar style="auto" />
<View style={{ flex: 1, justifyContent: "flex-start", margin: 20 }}>
<Button
title="Pay Now"
onPress={() =>
console.log(props.route.params)
}
containerStyle={styles.ButtonContainer}
buttonStyle={{ height: 60, justifyContent: "flex-start" }}
icon={<Icon name="cash" size={40} color="white" />}
/>
<Button
title="Pay on delivery"
containerStyle={styles.ButtonContainer}
buttonStyle={{ height: 60, justifyContent: "flex-start" }}
icon={<Icon name="cash" size={40} color="white" />}
/>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
ButtonContainer: {
width: 380,
},
});
export default PaymentOptionScreen;
here is a snippet of the of the app.js it may help
<AuthContext.Provider value={authContext}>
<NavigationContainer>
<Drawer.Navigator
initialRouteName="Home"
drawerContent={(props) => <DrawerContent {...props} />}
>
<Drawer.Screen name="Home" component={HomeStackScreen}/>
<Drawer.Screen name="Profile" component={ProfileStackScreen}/>
<Drawer.Screen name="Bookings" component={BookingsStackScreen}/>
<Drawer.Screen name="payment-options" component={PaymentOptionsScreenStack}/>
<Drawer.Screen name="Add Item" component={AddItemStackScreen}/>
<Drawer.Screen name="Settings" component={SettingsStackScreen}/>
<Drawer.Screen name="Messages" component={MessagesStackScreen}/>
</Drawer.Navigator>
</NavigationContainer>
</AuthContext.Provider>

Can you print the props? I think you have to pass it as object {props}
If you are using navigation 5.0 . Try this
const App=({navigation, route })=>{
const uuid = route.param;
return (
<View</View>
);
}

Related

FlatList - react native not scrolling

I am unable to get my Flatlist to scroll in my expo react native app. At the moment it is just static, displaying a grid of images int he Flatlist with no scrolling functionality. Please can someone advise?
I am unable to get my Flatlist to scroll in my expo react native app. At the moment it is just static, displaying a grid of images int he Flatlist with no scrolling functionality. Please can someone advise?
import { StyleSheet, Text, View, Button, TextInput, TouchableWithoutFeedback, Keyboard, FlatList, ActivityIndicator } from 'react-native';
import { Image } from '#rneui/themed';
import ImageAPI from '../shared-components/ImageAPI';
export default function Home({ navigation }) {
const onCreate = () => {
console.log('create my image now');
};
return (
<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
<View style={styles.container}>
{/** Enter text prompt */}
<View style={styles.section1}>
<View style={styles.txtInputView}>
<TextInput
style={styles.txtInput}
placeholder='Enter a prompt - a description of what you want to create'
multiline={true}
numberOfLines={4}
/>
</View>
<View style={styles.buttonView}>
<Text
style={styles.createBtnText}
onPress={onCreate}
>Create</Text>
</View>
</View>
{/** PROMPT EXAMPLES */}
<View style={styles.section2}>
<View style={styles.section2_sub0}>
<Text style={styles.promptEgTxt}>Prompt Examples</Text>
</View>
<View style={styles.section2_sub1}>
<ImageAPI />
</View>
</View>
</View>
</TouchableWithoutFeedback>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
section1: {
flex: 2,
width: '100%',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#ffc6e2',
},
section2: {
flex: 5,
width: '100%',
backgroundColor: '#F8DB93',
},
// section3: {
// flex: 3,
// backgroundColor: '#BCF893',
// },
txtInputView: {
flex: 3,
width: '85%',
height: '50%',
alignItems: 'center',
justifyContent: 'center',
marginTop: 20,
marginBottom: 20
},
buttonView: {
flex: 2,
width: '70%',
alignItems: 'center',
justifyContent: 'center',
marginBottom: 20,
backgroundColor: '#EE4A4A',
borderRadius: 40
},
txtInput: {
borderColor: '#AAAAAA',
borderWidth: 2,
padding: 10,
borderRadius: 15,
// width: '85%',
// height: '50%',
width: '100%',
height: '100%',
fontSize: 15,
},
createBtnText: {
fontSize: 18,
fontWeight: 'bold',
// backgroundColor: '#EEEC4A'
},
section2_sub0: {
flex: 1,
width: '100%',
height: '100%',
backgroundColor: '#EEEC4A',
justifyContent: 'center',
},
promptEgTxt: {
fontSize: 15,
fontWeight: 'bold',
marginLeft: 10
},
section2_sub1: {
flex: 8,
width: '100%',
height: '100%',
backgroundColor: '#A9F889'
},
});
This is the ImageAPI.js file:
import React from 'react';
import { FlatList, SafeAreaView, StyleSheet, ActivityIndicator, View, ScrollView } from 'react-native';
import { Image } from '#rneui/themed';
const BASE_URI = 'https://source.unsplash.com/random?sig=';
const ImageAPI = () => {
return (
<>
<SafeAreaView>
<FlatList
data={[...new Array(10)].map((_, i) => i.toString())}
style={styles.list}
numColumns={2}
keyExtractor={(e) => e}
renderItem={({ item }) => (
<Image
transition={true}
source={{ uri: BASE_URI + item }}
containerStyle={styles.item}
PlaceholderContent={<ActivityIndicator />}
/>
)}
/>
</SafeAreaView>
</>
);
};
const styles = StyleSheet.create({
list: {
width: '100%',
backgroundColor: '#000',
},
item: {
aspectRatio: 1,
width: '100%',
flex: 1,
},
});
export default ImageAPI
you need to give it a fixed height and set the contentContainerStyle prop to { flexGrow: 1 }. This will allow the content inside the FlatList to exceed the bounds of the container and be scrollable.
<View style={styles.section2_sub1}>
<FlatList
contentContainerStyle={{ flexGrow: 1 }}
data={data}
renderItem={({ item }) => <ImageAPI data={item} />}
keyExtractor={(item) => item.id}
/>
</View>
Try adding flex according to your requirement to your <SafeAreaView> which is the parent to your <Flatlist> Something like this:
<>
<SafeAreaView style = {{flex: 8}} >
<FlatList
data={[...new Array(10)].map((_, i) => i.toString())}
style={styles.list}
numColumns={2}
keyExtractor={(e) => e}
renderItem={({ item }) => (
<Image
transition={true}
source={{ uri: BASE_URI + item }}
containerStyle={styles.item}
PlaceholderContent={<ActivityIndicator />}
/>
)}
/>
</SafeAreaView>
</>
Or remove the SafeAreaView if not required.
Both should work.

How to send Selected Custom Checkbox data to next page in react native?

Here I have created toggle custom checkboxes and those are rendered within FlatList with Name.
Now which checkboxes are checked i want to send those names into next screen using navigation.
So how can i implement that functionality, if anyone knows then please help me for the same.
/**Code For custom checkbox:**/
import React from "react";
import {
TouchableOpacity,
Image,
View,
SafeAreaView,
Text,
} from "react-native";
import { useState } from "react";
import IconAntDesign from "react-native-vector-icons/AntDesign";
export function CheckBoxCustom() {
const [count, setCount] = useState(0);
return (
<SafeAreaView>
<TouchableOpacity
style={{
backgroundColor: "white",
width: 20,
height: 20,
borderWidth: 2,
borderColor: "#ddd",
}}
onPress={() => setCount(!count)}
>
{count ? (
<IconAntDesign name="check" size={15} color={"black"} />
) : null}
</TouchableOpacity>
</SafeAreaView>
);
}
/**Code for FlatList:**/
import React, {useState} from 'react';
import {
SafeAreaView,
Text,
View,
TouchableOpacity,
Image,
StyleSheet,
FlatList,
Dimensions,
useWindowDimensions,
ScrollView,
Button,
} from 'react-native';
import Header from '../CustomComponents/RestaurentUI/Header';
import {CheckBoxCustom} from '../CustomComponents/RestaurentUI/Checkbox';
import {TextInput} from 'react-native-gesture-handler';
import {TabView, SceneMap, TabBar} from 'react-native-tab-view';
import {NavigationContainer, useNavigation} from '#react-navigation/native';
import GetCheckBoxData from './GetCheckBoxData';
const data = [
{
name: 'Lumlère brûlée',
status: 'Problems',
},
{
name: 'Aucune eau chaude',
status: 'Problems',
},
{
name: 'Lumlère brûlée',
status: 'Problems',
},
{
name: 'Service de ménage',
status: 'Problems',
},
{
name: 'AC non-fonctionnel',
status: 'Problems',
},
{
name: 'WIFI non-fonctionnel',
status: 'Problems',
},
{
name: 'Four non-fonctionnel',
status: 'Problems',
},
];
const renderItem = ({item, index}) => {
return (
<View>
<View style={{flexDirection: 'row'}}>
<CheckBoxCustom />
<Text style={{marginLeft: 10}}>{item.name} </Text>
</View>
</View>
);
};
const separator = () => {
return (
<View
style={{
height: 1,
backgroundColor: '#f1f1f1',
marginBottom: 12,
marginTop: 12,
}}
/>
);
};
const FirstRoute = () => (
<FlatList
style={{marginTop: 20}}
data={data}
keyExtractor={(e, i) => i.toString()}
renderItem={renderItem}
ItemSeparatorComponent={separator}
/>
);
const SecondRoute = () => (
<View style={[styles.scene, {backgroundColor: 'white'}]} />
);
const initialLayout = {width: Dimensions.get('window').width};
const renderScene = SceneMap({
first: FirstRoute,
second: SecondRoute,
});
const ReportScreen = ({navigation}) => {
const nav = useNavigation();
const layout = useWindowDimensions();
const [index, setIndex] = useState(0);
const [routes] = useState([
{key: 'first', title: 'Problemes'},
{key: 'second', title: 'Besoins complémentaitaires'},
]);
const goToScreen = () => {
navigation.navigate('GetCheckBoxData', {title: 'Hii all'});
};
const [checked, setChecked] = useState({});
const checkToggle = id => {
setChecked(checked => ({
...checked,
[id]: !checked[id],
}));
};
return (
<SafeAreaView style={styles.safearea}>
<Header title="Report" />
<ScrollView showsVerticalScrollIndicator={false} bounces={false}>
<View style={{flexDirection: 'row', marginTop: 20}}>
<View style={{flex: 1, height: 1, backgroundColor: '#ccc'}} />
</View>
<View style={styles.cardView}>
<View style={styles.subView}>
<Image
style={styles.image}
source={require('../Assets/UIPracticeImage/H1.jpg')}
/>
<View style={styles.internalSubView}>
<View style={styles.nameView}>
<Text style={styles.nameText}>Pine Hill Green Caban</Text>
</View>
<View style={styles.dateView}>
<Text style={styles.dateText}>May 22-27</Text>
</View>
</View>
</View>
</View>
<View style={{flexDirection: 'row'}}>
<View style={{flex: 1, height: 1, backgroundColor: '#ccc'}} />
</View>
<View
style={{
// backgroundColor: 'lime',
flex: 1,
height: 385,
width: '100%',
}}>
<TabView
navigationState={{index, routes}}
renderScene={renderScene}
onIndexChange={setIndex}
initialLayout={initialLayout}
style={styles.container}
renderTabBar={props => (
<TabBar
tabStyle={{alignItems: 'flex-start', width: 'auto'}}
{...props}
renderLabel={({route, color}) => (
<Text style={{color: 'black'}}>{route.title}</Text>
)}
style={{backgroundColor: 'white'}}
/>
)}
/>
</View>
<Button title="Click me" onPress={goToScreen} />
</ScrollView>
</SafeAreaView>
);
};
export default ReportScreen;
const styles = StyleSheet.create({
safearea: {
marginHorizontal: 20,
},
cardView: {
borderRadius: 10,
marginVertical: 10,
paddingVertical: 8,
},
subView: {
flexDirection: 'row',
},
image: {
height: 80,
width: 110,
borderRadius: 10,
},
internalSubView: {
justifyContent: 'space-between',
flex: 1,
},
nameView: {
justifyContent: 'space-between',
flexDirection: 'row',
alignItems: 'center',
marginLeft: 10,
},
nameText: {
fontWeight: 'bold',
width: '45%',
fontSize: 15,
},
dateView: {
flexDirection: 'row',
alignItems: 'center',
marginLeft: 10,
justifyContent: 'space-between',
},
dateText: {
width: 80,
},
listTab: {
flexDirection: 'row',
marginBottom: 20,
marginTop: 20,
},
btnTab: {
borderWidth: 3,
borderColor: 'white',
flexDirection: 'row',
marginRight: 10,
},
btnTabActive: {
borderWidth: 3,
borderBottomColor: '#fdd83d',
borderColor: 'white',
},
scheduleButton: {
backgroundColor: '#fdd83d',
alignItems: 'center',
paddingVertical: 15,
borderRadius: 10,
marginTop: 15,
},
container: {
marginTop: 20,
},
scene: {
flex: 1,
},
});
[![UI image][1]][1]
[1]: https://i.stack.imgur.com/AuLT8.png
You may want to lift the checkbox state to the parent component, i.e. make the checkboxes controlled, and collect the checked checkbox values. For this I'm assuming your data items have an id property, but any unique item property will suffice.
Example:
export function CheckBoxCustom({ checked, onPress }) {
return (
<SafeAreaView>
<TouchableOpacity
style={{
backgroundColor: "white",
width: 20,
height: 20,
borderWidth: 2,
borderColor: "#ddd",
}}
onPress={onPress}
>
{checked ?? <IconAntDesign name="check" size={15} color={"black"} />}
</TouchableOpacity>
</SafeAreaView>
);
}
...
const [checked, setChecked] = useState({});
const checkToggle = id => {
setChecked(checked => ({
...checked,
[id]: !checked[id],
}));
};
const renderItem = ({ item, index }) => {
return (
<View>
<View style={{ flexDirection: "row" }}>
<CheckBoxCustom
checked={checked[item.id]}
onPress={() => checkToggle(item.id)}
/>
<Text style={{ marginLeft: 10 }}>{item.name}</Text>
</View>
</View>
);
};
<FlatList
data={dataList}
keyExtractor={(e, i) => i.toString()}
renderItem={renderItem}
ItemSeparatorComponent={separator}
/>;
If your data hasn't any good GUID candidates then I suggest augmenting your data to include good GUIDs.
To pass the checked/selected items filter the dataList array.
Example:
const selected = dataList.filter(
item => checked[item.id]
);
// pass selected in navigation action

FlatList react native not scrolling

I have made sure that the parent Views contain flex:1, and I have wrapped the FlatList in a view with Flex 1 but nothing I seem to try enables my flat list to scroll.
I have gone through previous posts and none of the solutions have worked
Any help or suggestions would be greatly appreciated.
This is my code in order from parent to children
const App = () => {
return (
<View style={styles.container}>
<AuthProvider>
<Home />
</AuthProvider>
</View>
);
};
const styles = StyleSheet.create({
container: {flex: 1},
});
export default App;
const Home = () => {
const [userAuth] = useContext(AuthContext);
//{userAuth.auth && <Header title={'Stokebook'} />}
return (
<View style={styles.container}>
{userAuth.auth && <Profile />}
{!userAuth.auth && <LoginHome />}
</View>
);
};
const styles = StyleSheet.create({
container: {flex: 1},
});
const Profile = () => {
const [userAuth] = useContext(AuthContext);
const [Posts, setPosts] = useState();
const [isLoading, setisLoading] = useState(true);
//Loading screen will live here
useEffect(() => {
axios({
method: 'get',
url: 'http://192.168.1.112:3000/posts',
headers: {
Authorization: `${userAuth.token}`,
},
})
.then(response => {
setPosts(response.data.flat());
})
.then(setisLoading(false))
.catch(err => setPosts(err));
}, []);
return (
<View style={styles.PostContainer}>
<FlatList
contentContainerStyle={{height: '100%'}}
data={Posts}
renderItem={({item}) => <Post post={item} />}
/>
</View>
);
};
const styles = StyleSheet.create({
PostContainer: {
backgroundColor: 'grey',
flex: 1,
},
});
const Post = ({post}) => {
return (
<View style={styles.PostContainer}>
<View style={styles.PostHeader}>
<View style={styles.ProfileInfoView}>
<Text>Michael Wong</Text>
<Text>Yesterday at 6.30pm at point leo</Text>
</View>
</View>
<View style={styles.WaveInfo}>
<View>
<Text>Wave height </Text>
<Text> 6ft</Text>
</View>
<View>
<Text>tide </Text>
<Text>low</Text>
</View>
<View>
<Text>Break</Text>
<Text>crunchies</Text>
</View>
<View>
<Text>Wind </Text>
<Text>NE 10km/hr</Text>
</View>
</View>
<View style={styles.ImageView}>
<Image
source={require('../wave.webp')}
style={{flex: 1, width: undefined, height: undefined}}
/>
</View>
<View style={styles.FeedbackView}>
<Text>
<Icon name="thumbs-up" size={15} color="black" /> 13
</Text>
<Text>3 comments</Text>
</View>
<View style={styles.FooterView}>
<View style={styles.IconView}>
<Icon name="thumbs-up" size={30} color="white" />
<Icon name="envelope" size={30} color="white" />
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
PostContainer: {
backgroundColor: 'beige',
height: '80%',
},
PostHeader: {
height: '20%',
padding: '4%',
flexDirection: 'row',
},
Profileimg: {
height: 30,
width: 30,
borderRadius: 30,
},
ProfileInfoView: {
paddingLeft: '5%',
justifyContent: 'space-around',
},
WaveInfo: {
borderTopWidth: 1,
height: '12%',
flexDirection: 'row',
justifyContent: 'space-evenly',
alignItems: 'center',
},
ImageView: {
height: '60%',
width: '100%',
},
FeedbackView: {
height: '10%',
backgroundColor: 'beige',
flexDirection: 'row',
justifyContent: 'space-between',
padding: '3%',
alignItems: 'center',
},
FooterView: {
width: '100%',
height: '15%',
flexDirection: 'row',
justifyContent: 'center',
backgroundColor: 'black',
borderBottomColor: 'grey',
borderBottomWidth: 12,
},
IconView: {
height: '100%',
width: '70%',
justifyContent: 'space-around',
alignItems: 'center',
flexDirection: 'row',
},
});
export default Post;

How to scroll To next item on a button click using FlatList in React Native?

I have an array of months which I am using to display months using a horizontal FlatList. I want the months to change using 2 buttons that are forward button to change the month in increasing order i.e from January to February and so on and a back button to change the month backwards i.e from January to December.
How can I make the buttons do so. Below monthName is an array that contains all the month names.
<ScrollView style={{flexGrow: 1}}>
<View style={{flex: 1, backgroundColor: '#fff', height: hp('130')}}>
<View
style={{
justifyContent: 'space-evenly',
width: wp('48'),
}}>
<FlatList
data={monthName}
pagingEnabled={true}
showsHorizontalScrollIndicator={false}
renderItem={(month, index) => (
<View>
<Months
showMonth={month.item}
id={month.id}
refer={flatRef}
/>
</View>
)}
keyExtractor={(item, index) => item.id.toString()}
horizontal
// snapToInterval={Dimensions.get('window').width}
snapToAlignment={'center'}
ref={(node) => (flatRef = node)}
/>
</View>
<View
style={{
justifyContent: 'space-evenly',
width: wp('12'),
}}>
{/* {} */}
<IonIcons.Button --> the button that makes the month increment.
name="arrow-forward"
size={25}
backgroundColor="white"
color="black"
// onPress={() => console.log('pressed')}
onPress={() => {
flatRef.scrollToIndex({index: ?});
}}
/>
</View>
</View>
</ScrollView>
try to access ref using current and it should work
this.flatRef.current.scrollToIndex({index: monthName.length > this.state.currentindex ? this.state.currentindex++ : this.state.currentindex });
import React, { useRef } from 'react';
import {
FlatList,
StyleSheet,
Text,
TouchableOpacity,
View
} from 'react-native';
import { wp } from '../../constants/scaling';
import { colors } from '../../constants/theme';
import bookingprocess from '../../data/BookingProcess';
import { textStyles } from '../../styles/textStyles';
import { RFValue } from 'react-native-responsive-fontsize';
import AntDesign from 'react-native-vector-icons/AntDesign';
const BookingProcess = ({}) => {
const flatListRef = useRef(FlatList);
const nextPress = index => {
if (index <= 2) {
flatListRef?.current?.scrollToIndex({
animated: true,
index: index + 1
});
}
};
const backPress = index => {
if (index >= 1) {
flatListRef?.current?.scrollToIndex({
animated: true,
index: index - 1
});
}
};
return (
<View
style={{
...styles.cardView,
padding: 0,
elevation: 0,
borderWidth: 1,
borderColor: '#f2f2f2',
overflow: 'hidden'
}}>
<View
style={{
padding: wp(2),
backgroundColor: colors.primaryColor
}}>
<Text
style={{
...textStyles.heading,
color: '#fff'
}}>
Booking Process
</Text>
</View>
<Text
style={{
...textStyles.mediumheading,
padding: wp(2),
paddingBottom: 0
}}>
You can reserve your parking slot in advance. Please follow
these four simple steps to book your parking slot.
</Text>
<FlatList
data={bookingprocess}
horizontal={true}
ref={flatListRef}
contentContainerStyle={{ padding: wp(2) }}
showsHorizontalScrollIndicator={false}
keyExtractor={(item, index) => item.id}
renderItem={({ item, index }) => {
return (
<View style={styles.innerCard}>
{item.image}
<View style={styles.ButtonBox}>
<TouchableOpacity
onPress={() => backPress(index)}
style={{
backgroundColor: colors.secondaryColor,
borderRadius: wp(50)
}}>
<AntDesign
name="leftcircle"
size={RFValue(25)}
color={colors.primaryColor}
/>
</TouchableOpacity>
<TouchableOpacity
onPress={() => nextPress(index)}
style={{
backgroundColor: colors.secondaryColor,
borderRadius: wp(50)
}}>
<AntDesign
name="rightcircle"
size={RFValue(25)}
color={colors.primaryColor}
/>
</TouchableOpacity>
</View>
<View style={styles.innercardHeaderView}>
<Text style={styles.headingTextNumber}>
{item.id}. {item.title}
</Text>
</View>
<Text style={styles.description}>
{item.description}
</Text>
</View>
);
}}
/>
</View>
);
};
export default BookingProcess;
const styles = StyleSheet.create({
cardView: {
backgroundColor: colors.white,
margin: wp(2),
elevation: 4,
borderRadius: wp(2),
padding: wp(2),
width: wp(94)
},
innerCard: {
margin: wp(2),
borderRadius: wp(2),
padding: wp(0),
paddingTop: 0,
paddingHorizontal: 0,
overflow: 'hidden',
width: wp(90),
elevation: 5,
marginLeft: 0,
padding: wp(2),
backgroundColor: '#fff'
},
ButtonBox: {
position: 'absolute',
flexDirection: 'row',
right: 0,
justifyContent: 'space-between',
width: wp(20),
padding: wp(2)
},
innercardHeaderView: {
backgroundColor: '#0000',
flexDirection: 'row',
padding: wp(2),
paddingBottom: 0,
alignItems: 'center'
},
headingTextNumber: {
...textStyles.heading,
color: colors.primaryColor,
textAlign: 'center',
alignSelf: 'center',
textAlignVertical: 'center'
},
description: {
...textStyles.mediumheading,
paddingHorizontal: wp(2),
textAlign: 'justify'
}
});
Instead of using a FlatList I would suggest you to make a state variable and execute it like this
Working example - Here
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { AntDesign } from '#expo/vector-icons';
...
const [SelectMonth, SetSelectMonth] = React.useState(monthName[0]);
const NextPress = () => {
if (SelectMonth.id !== 12) {
let temp = monthName.find((c) => c.id === SelectMonth.id + 1);
if (temp) {
SetSelectMonth(temp);
}
}
};
const PrevPress = () => {
if (SelectMonth.id !== 1) {
let temp = monthName.find((c) => c.id === SelectMonth.id - 1);
if (temp) {
SetSelectMonth(temp);
}
}
};
return (
<View style={styles.container}>
<View style={styles.CalenderBox}>
<AntDesign
name="caretleft"
size={30}
color="black"
onPress={() => PrevPress()}
/>
<View style={styles.MonthNameBox}>
<Text style={{ fontWeight: 'bold', fontSize: 24 }}>
{SelectMonth.name}
</Text>
</View>
<AntDesign
name="caretright"
size={30}
color="black"
onPress={() => NextPress()}
/>
</View>
</View>
);

Webview Uri Redirect by scanning barcodes with React Native, Expo

I am creating a barcode scanner using React Native and Expo.
I am trying to pass a new URL to a WebView after scanning a barcode.
But I am not sure how.
Please help.
export default function App() {
const [hasPermission, setHasPermission] = useState(null);
const [scanned, setScanned] = useState(false);
const [modalVisible, setModalVisible] = useState(false);
useEffect(() => {
(async () => {
const { status } = await BarCodeScanner.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
const handleBarCodeScanned = ({ type, data }) => {
setScanned(true);
setModalVisible(true);
};
if (hasPermission === null) {
return <Text>Requesting for camera permission</Text>;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<View
style={{
flex: 1,
flexDirection: 'column'
}}>
<Modal
animationType="slide"
transparent={false}
visible={modalVisible}
onRequestClose={() => {
setScanned(false);
}}>
<View style={{ flex: 1 }}>
<WebView
style={{ flex: 1 }}
source={{ uri: 'http://domain.biz/' }}
/>
<TouchableHighlight
style={{
backgroundColor:'black',
padding: 15,
alignItems: 'center'
}}
onPress={() => {
setModalVisible(!modalVisible);
setScanned(false);
}}
underlayColor='slategray'
>
<Text style={{ color:'white', fontSize: 15 }}>Re Scan</Text>
</TouchableHighlight>
</View>
</Modal>
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}>
<View style={{ marginBottom: 100 }}>
<View style={{ alignItems: 'center', marginBottom: 5 }}>
<Image
style={{
width: 100,
height: 100,
resizeMode: 'contain',
marginBottom: 20,
}}
source={{ uri: 'http://domain.biz/img/logo_dark.png' }}
/>
<Text style={{ color: 'white', fontSize: 20, fontWeight: 'bold', paddingBottom: 10}}>
QR Code Reader v0.5
</Text>
</View>
<View
style={{
borderColor: 'white',
borderTopWidth: 5,
borderBottomWidth: 5,
borderLeftWidth: 1,
borderRightWidth: 1,
paddingVertical: 80,
paddingHorizontal: 100,
}}
/>
<View style={{ alignItems: 'center', marginTop: 5 }}>
<Text style={{ color: 'white', fontSize: 15}}>
QR Scan...
</Text>
</View>
</View>
</BarCodeScanner>
</View>
);
}
I am creating a barcode scanner using React Native and Expo.
I am trying to pass a new URL to a WebView after scanning a barcode.
But I am not sure how.
Please help.
This should do the work. I save the url from the scanner in state.uri and use that instead of a static string.
For testing purposes I used this barcode which leads to this answer:
Best, Paul
import React, { useState, useEffect } from 'react';
import { Text, View, StyleSheet, Button, Modal, TouchableHighlight, Image } from 'react-native';
import { WebView } from 'react-native-webview';
import { BarCodeScanner } from 'expo-barcode-scanner';
export default function App(){
const [hasPermission, setHasPermission] = useState(null);
const [scanned, setScanned] = useState(true);
const [modalVisible, setModalVisible] = useState(true);
const [uri, setUri] = useState('https://stackoverflow.com/questions/61977154/webview-uri-redirect-by-scanning-barcodes-with-react-native-expo');
useEffect(() => {
(async () => {
const { status } = await BarCodeScanner.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
const handleBarCodeScanned = ({ type, data }) => {
setScanned(true);
setModalVisible(true);
// console.warn("Scan returned " + data);
setUri({ uri: data })
};
if (hasPermission === null) {
return <Text>Requesting for camera permission</Text>;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<View
style={{
flex: 1,
flexDirection: 'column'
}}>
<Modal
animationType="slide"
transparent={false}
visible={modalVisible}
onRequestClose={() => {
setScanned(false);
}}>
<View style={{ flex: 1 }}>
<WebView
style={{ flex: 1 }}
source={{uri: uri['uri']}}
/>
<TouchableHighlight
style={{
backgroundColor:'black',
padding: 15,
alignItems: 'center'
}}
onPress={() => {
setModalVisible(!modalVisible);
setScanned(false);
}}
underlayColor='slategray'
>
<Text style={{ color:'white', fontSize: 15 }}>Re Scan</Text>
</TouchableHighlight>
</View>
</Modal>
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}>
<View style={{ marginBottom: 100 }}>
<View style={{ alignItems: 'center', marginBottom: 5 }}>
<Image
style={{
width: 100,
height: 100,
resizeMode: 'contain',
marginBottom: 20,
}}
source={{ uri: 'http://domain.biz/img/logo_dark.png' }}
/>
<Text style={{ color: 'white', fontSize: 20, fontWeight: 'bold', paddingBottom: 10}}>
QR Code Reader v0.5
</Text>
</View>
<View
style={{
borderColor: 'white',
borderTopWidth: 5,
borderBottomWidth: 5,
borderLeftWidth: 1,
borderRightWidth: 1,
paddingVertical: 80,
paddingHorizontal: 100,
}}
/>
<View style={{ alignItems: 'center', marginTop: 5 }}>
<Text style={{ color: 'white', fontSize: 15}}>
QR Scan...
</Text>
</View>
</View>
</BarCodeScanner>
</View>
);
}
Here it is, but I have passed the data from the other page name:index.js.
You can use the linking component to open every URL passed through {data}
import React from "react";
import { View, Text, Linking, TouchableOpacity } from "react-native";
const detail = ({ route, navigation }) => {
const data = route.params;
const [uri, setUri] = React.useState({});
return (
<View>
<TouchableOpacity onPress={() => Linking.openURL(data)}>
<Text>{data}</Text>
</TouchableOpacity>
</View>
);
};
export default detail;