React Native Drawer Navigation not showing on each page - react-native

I am very new to React Native and this is the reason why I need your help now. I try to create an app with a normal Sidemenu (Burgermenu) which should apear on ech page. And I have a Bottom tab bar which should appear on 3 pages. The problem is, that on those 3 pages the Sidemenu is not displayed. What am I doing wrong?
This is the first called Page:
import * as React from 'react';
import DrawerNavigator from './DrawerNavigator'
function App() {
return (
<DrawerNavigator />
);
}
export default App;
This is the Sidemenu (DrawerNavigator.js):
import * as React from 'react'
import { createDrawerNavigator, DrawerContentScrollView, DrawerItemList, DrawerItem } from '#react-navigation/drawer'
import ProjekteStackNavigator from './side_menu/Projekte'
import DashboardStackNavigator from './side_menu/Desktop'
...
import { Text, View, StyleSheet} from 'react-native';
//##################### ICONS Importieren #####################
import AppLoading from 'expo-app-loading';
import { useFonts } from 'expo-font';
import { createIconSetFromIcoMoon } from '#expo/vector-icons';
const Icon = createIconSetFromIcoMoon(
require('../../assets/icomoon/selection.json'),
'IcoMoon',
'zepra_icons.ttf'
);
//#############################################################
const Drawer = createDrawerNavigator()
function myLogout(){
navigation.navigate("LoginScreen");
}
const DrawerNavigator = () => {
const [fontsLoaded] = useFonts({ IcoMoon: require('../../assets/icomoon/zepra_icons.ttf') });
if (!fontsLoaded) {
return <AppLoading />;
}
return (
<Drawer.Navigator initialRouteName="Home" drawerContent={props => {
return (
<DrawerContentScrollView {...props} scrollIndicatorInsets={{ right: 1 }}>
<DrawerItemList {...props} />
<DrawerItem label="Logout" labelStyle={{marginLeft:-18, fontSize: 15,}}
icon={({ focused, color, size }) => <Icon2 style={{marginLeft:8}} color={focused ? '#1585b5' : '#6cbabf'} size={26} name={focused ? 'log-out-outline' : 'log-out-outline'} /> }
onPress={() => props.navigation.navigate("StartScreen") } />
</DrawerContentScrollView>
)
}}>
<Drawer.Screen name="Dashboard" component={DashboardStackNavigator}
options={{
drawerLabel: 'Dashboard',
drawerLabelStyle:{ marginLeft:-20, fontSize: 15},
drawerIcon: ({focused, size}) => (
<Icon name='HAUS_3' size={35} color={focused ? '#1585b5' : '#6cbabf'} />
)}}/>
<Drawer.Screen name="Projekte" component={ProjekteStackNavigator}
options={{
drawerLabel: 'Projekte',
drawerLabelStyle:{marginLeft:-20, fontSize: 15},
drawerIcon: ({focused, size}) => (
<Icon name='PROJEKTE_ALLE' size={35} color={focused ? '#1585b5' : '#6cbabf'} />
)}}/>
</Drawer.Navigator>
)
}
export default DrawerNavigator
This is the Projects Page which calls the Pages with the Bottom Tab:
import React, { useState, useEffect } from 'react';
import {Alert, View, Text, Modal, StyleSheet, Pressable, ListView, FlatList, TouchableOpacity } from 'react-native'
import { createStackNavigator } from '#react-navigation/stack'
import { theme } from '../../core/theme';
import clientConfig from '../../../client-config';
import Icon2 from 'react-native-vector-icons/Ionicons';
import ProjektOverview from '../ProjektOverview'
//##################### ICONS Importieren #####################
import AppLoading from 'expo-app-loading';
import { useFonts } from 'expo-font';
import { createIconSetFromIcoMoon } from '#expo/vector-icons';
const Icon = createIconSetFromIcoMoon(
require('../../../assets/icomoon/selection.json'),
'IcoMoon',
'zepra_icons.ttf'
);
//#############################################################
const Stack = createStackNavigator()
const ModalComponent = ({ modalVisible, setModalVisible, children }) => {
return (
<Modal
animationType="slide"
transparent={true}
style={styles.centeredView}
visible={modalVisible}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
setModalVisible(!modalVisible);
}}>
{children}
</Modal>
);
};
export default function ObjectsScreen({ navigation }){
const [modalVisible, setModalVisible] = useState(false);
const [modal2Visible, setModal2Visible] = useState(false);
const [data, setData] = React.useState(null);
const [fontsLoaded] = useFonts({ IcoMoon: require('../../../assets/icomoon/zepra_icons.ttf') });
const onClickHandler =(data)=>()=> {
navigation.navigate('ProjektOverview', {data});
};
const comp_id = localStorage.getItem('anwender_unternehmen');
if ( localStorage.getItem( 'token' )!=null ) {
React.useEffect(() => {
async function getData() {
try {
const siteUrl = clientConfig.siteUrl + '/wp-json/zep/v1/projekt-liste/' + comp_id;
const response = await fetch(siteUrl, {
method: 'GET',
headers: {
Authorization: 'Bearer '+localStorage.getItem( 'token' )
}
})
if (response.status === 200) {
let json = await response.json();
const array = json.data;
const error = array.error_code;
if(error == 0){
const projekte = array.data_values[0];
setData(projekte);
}else{
setData(1201);
}
}else {
if(response.status === 503) {
setModalVisible(true);
}
if(response.status === 403) {
setModal2Visible(true);
}
throw new Error(`failed due to status code ${response.status}`);
}
} catch (err) {
console.log(err);
}
}
getData();
}, []);
if(data != 1201){
return (
<FlatList
data={data}
keyExtractor={(item, index) => String(index) + item.value}
renderItem={({item, index})=>(
<TouchableOpacity onPress={ onClickHandler({item}) } >
<View style={{ textAlign: 'left', borderColor:'#6cbabf', borderBottomWidth: 1, padding:10, margin:0, flexDirection: "row", alignItems: "center"}}>
<Text style={{textAlign: 'left', marginLeft:15, fontSize: 16, fontWeight: '500',}}>
{item.projekt_name} {item.projekt_nummer}</Text>
<View style={{flex:1, alignItems: "center", flexDirection: "row", justifyContent: "flex-end", marginRight:30}}>
<Icon name='PROJEKTE_BEARBEITEN' size={40} color={'#6cbabf'} />
<Icon2 name='eye-outline' size={10} color={'#6cbabf'} style={{padding:-100, margin:-17, bottom:-7.5}} />
</View>
</View>
</TouchableOpacity>
)}/>
); // return
}else{
return (
<View style={{borderColor:'#6cbabf',borderWidth: 1,borderRadius:5, padding:15,margin:12,}}>
<View style={{justiftyContent:"center", alignItems:"center"}}>
<Icon name='PROJEKTE_ALLE' size={100} color={'#6cbabf'} />
</View>
<Text style={{textAlign: 'left', fontSize: 16, fontWeight: '700', paddingBottm:15,}}>Sie haben noch keine Projekte erstellt.</Text>
<Text style={{fontSize: 12}}> </Text>
<Text style={{textAlign: 'center', fontSize: 13}}>Projekte können nur in der Desktopanwendung verwalten werden.</Text>
</View>
); // return
}
}else{
navigation.navigate('Dashboard');
}
return (
<>
<ModalComponent
modalVisible={modalVisible}
setModalVisible={(val) => {
setModalVisible(val);
}}>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<Text style={styles.modalText}>Fehler 503</Text>
<Text style={styles.modalText}>Ein unbekannter Fehler ist aufgetreten!.</Text>
<Pressable
style={[styles.button, styles.buttonClose]}
onPress={() => setModalVisible(!modalVisible)}>
<Text style={styles.textStyle}>Ok</Text>
</Pressable>
</View>
</View>
</ModalComponent>
<ModalComponent
modalVisible={modal2Visible}
setModalVisible={(val) => {
setModal2Visible(val);
}}>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<Text style={styles.modalText}>Fehler 403</Text>
<Text style={styles.modalText}>Bitte loggen Sie sich erneut ein!</Text>
<Pressable
style={[styles.button, styles.buttonClose]}
onPress={() => setModal2Visible(!modal2Visible)}>
<Text style={styles.textStyle}>Ok</Text>
</Pressable>
</View>
</View>
</ModalComponent>
</>
);
}
This is the Bottom Navigator:
import * as React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
//##################### ICONS Importieren #####################
import AppLoading from 'expo-app-loading';
import { useFonts } from 'expo-font';
import { createIconSetFromIcoMoon } from '#expo/vector-icons';
const Icon = createIconSetFromIcoMoon(
require('../../assets/icomoon/selection.json'),
'IcoMoon',
'zepra_icons.ttf'
);
//#############################################################
//##################### Seiten importieren #####################
import ProjectsScreen from './ProjectScreen';
import WaermeschutzScreen from './tabs/waermeschutz';
import BegehungenScreen from './tabs/begehungen';
//##############################################################
//##################### Menünamen für Buttontab ################
const projectsName = "Projekte";
const waermeschutzName = "Wärmeschutz";
const begehungenName = "Begehungen";
//##############################################################
//#################### BUTTON-TAB erstellen #####################
const Tab = createBottomTabNavigator();
function MainContainer() {
// Load the icon font before using it
const [fontsLoaded] = useFonts({ IcoMoon: require('../../assets/icomoon/zepra_icons.ttf') });
if (!fontsLoaded) {
return <AppLoading />;
}
return (
<Tab.Navigator
initialRouteName={projectsName}
screenOptions={({ route }) => ({
headerShown: false,
tabBarIcon: ({ focused, color, size }) => {
let iconName;
let rn = route.name;
if (rn === projectsName) {
iconName = focused ? 'PROJEKTE_ALLE' : 'PROJEKTE_ALLE';
} else if (rn === waermeschutzName) {
iconName = focused ? 'HAUS_3' : 'HAUS_3';
} else if (rn === begehungenName) {
iconName = focused ? 'NOTIZ_ERSTELLEN' : 'NOTIZ_ERSTELLEN';
}
// You can return any component that you like here!
return <Icon name={iconName} size={43} color={color} />;
},
'tabBarActiveTintColor': '#4283b1',
'tabBarInactiveTintColor': '#5db8bd',
'tabBarStyle':{ 'paddingTop':4, 'height':90 },
'tabBarLabelStyle':{ 'paddingTop':3, 'fontSize':13 }
})}>
<Tab.Screen name={projectsName} component={ProjectsScreen} />
<Tab.Screen name={waermeschutzName} component={WaermeschutzScreen} />
<Tab.Screen name={begehungenName} component={BegehungenScreen} />
</Tab.Navigator>
);
}
export default MainContainer;
And this is the page with the ProjectsScreen:
import React, { useState, useEffect } from 'react';
import {Alert, View, Text, Modal, StyleSheet, ImageBackground, ScrollView, FlatList , TouchableOpacity, Linking} from 'react-native';
import Background from '../components/Background_2';
import BackButton from '../components/BackButton';
import helpers from '../components/Data_funks';
import Icon2 from 'react-native-vector-icons/Ionicons';
import DrawerNavigator from './DrawerNavigator'
//##################### ICONS Importieren #####################
import AppLoading from 'expo-app-loading';
import { useFonts } from 'expo-font';
import { createIconSetFromIcoMoon } from '#expo/vector-icons';
const Icon = createIconSetFromIcoMoon( require('../../assets/icomoon/selection.json'), 'IcoMoon', 'zepra_icons.ttf');
const Bold = ({ children }) => <Text style={{ fontWeight: 'bold' }}>{children}</Text>
//#############################################################
//export default function ProjectsScreen({ route, navigation }) {
function ProjectsScreen({ route, navigation }) {
const data = route.params['data'];
const [projekte_data, setProjektdata] = useState([]);
const [bauherr, setBauherr] = useState([]);
const [bauleiter, setBauleiter] = useState([]);
const [projektleiter, setProjektleiter] = useState([]);
const [sachbearbeiter, setSachbearbeiter] = useState([]);
const [objekte, getObjekte] = useState([]);
// Projektdaten ########################################################################
useEffect(() => {
const init = async () => {
await helpers.get_projekt_data(data.item.projekt_id).then(result =>{
setProjektdata(result.p_data[0]);
setBauherr(result.bauherr[0]);
setBauleiter(result.bauleiter[0]);
setProjektleiter(result.projektleiter[0]);
setSachbearbeiter(result.sachbearbeiter[0]);
})
}
;
init();
},[]);
//###################################################################################
// Objektdaten ########################################################################
useEffect(() => {
const init2 = async () => {
await helpers.getObjekte(data.item.projekt_id).then(result2 =>{
getObjekte(result2[0]);
})
}
;
init2();
},[]);
//###################################################################################
const onClickHandler =(data)=>()=> {
navigation.navigate('ProjektOverview', {data});
};
console.log(objekte);
return(
<ScrollView scrollIndicatorInsets={{ right: 1 }} contentContainerStyle={{ flexGrow: 1 }}>
<Background>
<DrawerNavigator />
<View style={{paddingTop:50,}}>
<Icon name='KRAN' size={80} color={'#6cbabf'} style={{textAlign: 'center',}} />
</View>
<View style={{paddingTop:10,}}>
{ data.item.projekt_name !='Kein Titel'? <Text style={styles.HeadNameStyle}>{data.item.projekt_name}
<Text>{"\n"}</Text>
{data.item.projekt_nummer}</Text> : <Text style={styles.HeadNameStyle}>{data.item.projekt_nummer}</Text> }
</View>
<View style={styles.tabsStyle}>
<View style={styles.row}>
<TouchableOpacity onPress={() => Linking.openURL(`tel:${bauleiter['kontakte_mobil']}`) }>
<Icon2 style={styles.icon} name='call-outline' size={22} color={'#6cbabf'} />
</TouchableOpacity>
<View style={styles.inputWrap}>
<Text style={styles.tabsHeader}><Bold>Bauleiter:</Bold> {bauleiter['kontakte_vorname']} {bauleiter['kontakte_vorname']}</Text>
</View>
<View style={styles.inputWrap2}>
<TouchableOpacity onPress={() => Linking.openURL(`tel:${bauleiter['kontakte_mail']}`) }>
<Icon2 style={styles.icon} name='md-mail-outline' size={22} color={'#6cbabf'} />
</TouchableOpacity>
</View>
</View>
<View style={styles.row}>
<TouchableOpacity onPress={() => Linking.openURL(`tel:${bauherr['kontakte_mobil']}`) }>
<Icon2 style={styles.icon} name='call-outline' size={22} color={'#6cbabf'} />
</TouchableOpacity>
<View style={styles.inputWrap}>
<Text style={styles.tabsHeader}><Bold>Bauherr:</Bold> {bauherr['kontakte_vorname']} {bauherr['kontakte_nachname']}</Text>
</View>
<View style={styles.inputWrap2}>
<TouchableOpacity onPress={() => Linking.openURL(`tel:${bauherr['kontakte_mail']}`) }>
<Icon2 style={styles.icon} name='md-mail-outline' size={22} color={'#6cbabf'} />
</TouchableOpacity>
</View>
</View>
<View style={styles.row}>
<TouchableOpacity onPress={() => Linking.openURL(`tel:${projektleiter['anwender_mobil']}`) }>
<Icon2 style={styles.icon} name='call-outline' size={22} color={'#6cbabf'} />
</TouchableOpacity>
<View style={styles.inputWrap}>
<Text style={styles.tabsHeader}><Bold>Projektleiter:</Bold> {projektleiter['anwender_vorname']} {projektleiter['anwender_nachname']}</Text>
</View>
<View style={styles.inputWrap2}>
<TouchableOpacity onPress={() => Linking.openURL(`tel:${projektleiter['anwender_mail']}`) }>
<Icon2 style={styles.icon} name='md-mail-outline' size={22} color={'#6cbabf'} />
</TouchableOpacity>
</View>
</View>
<View style={styles.row}>
<TouchableOpacity onPress={() => Linking.openURL(`tel:${sachbearbeiter['anwender_mobil']}`) }>
<Icon2 style={styles.icon} name='call-outline' size={22} color={'#6cbabf'} />
</TouchableOpacity>
<View style={styles.inputWrap}>
<Text style={styles.tabsHeader}><Bold>Sachbearbeiter:</Bold> {sachbearbeiter['anwender_vorname']} {sachbearbeiter['anwender_nachname']}</Text>
</View>
<View style={styles.inputWrap2}>
<TouchableOpacity onPress={() => Linking.openURL(`tel:${sachbearbeiter['anwender_mail']}`) }>
<Icon2 style={styles.icon} name='md-mail-outline' size={22} color={'#6cbabf'} />
</TouchableOpacity>
</View>
</View>
</View>
<View style={styles.objectHeader}>
{ objekte !=''? <Text style={styles.HeadNameStyle}>Objekte</Text>: null}
</View>
<FlatList style={styles.FlatList}
data={objekte}
scrollEnabled={false}
keyExtractor={(item, index) => String(index) + item.value}
renderItem={({item, index})=>(
<View style={styles.Container}>
<View style={styles.navBar}>
<Icon name='HAUS_3' size={110} color={'#6cbabf'} />
<View style={styles.centerContainer}>
<Text style={styles.centerText}>{item.objekt_name} </Text>
<Text style={styles.centerText}>{item.objekt_nummer} </Text>
</View>
</View>
<Text>{<Bold>Adresse:</Bold>} {item.objekt_strasse}</Text>
<Text>{' '} {item.objekt_plz}, {item.objekt_ort}</Text>
<Text>{' '}</Text>
<Text>{<Bold>Nutzung:</Bold>} {item.objekt_typ}, {<Bold>Vorhaben:</Bold>} {item.objekt_sanierungs_art}</Text>
</View>
)}/>
<Text>{''}</Text>
</Background>
</ScrollView>
)
}
export default ProjectsScreen;

Related

Stripe payment trigger All modals to open

When i put credits and make a payment the payment is succesfull but for some reason after the payment stripe is triggering all modals to open(from header), like it setting true all the modals , anyone know why ? ( The modal is from another compoenent name "Header" its working fine with everything else in my app .
Code below :
Merry Christmas :)
//React imports
import React, { useState } from 'react';
import { StyleSheet, View, Text, Pressable, Alert, Image , KeyboardAvoidingView , Dimensions , Platform} from 'react-native';
import { useNavigation , useFocusEffect } from '#react-navigation/native';
//Icon imports
import { AntDesign } from '#expo/vector-icons';
import { FontAwesome5 } from '#expo/vector-icons';
//API imports
import axios from 'axios';
import { StripeProvider, CardField, CardFieldInput, createToken, confirmPayment } from '#stripe/stripe-react-native';
import { Buffer } from "buffer";
//useConfirmPayment,useStripe
//My imports
import Header from './Header';
//.Env imports
import {URL} from '#env';
export default function Payment({route}) {
//Constructors for Card Details
const [card, setCard] = useState(CardFieldInput.Details | null);
//Use of navigate Hook
const navigation = useNavigation();
//My local variables
const bookItem = route.params.paramKey;
const bookID = bookItem.id;
const bookPrice = bookItem.Price;
const bookImage = bookItem.image;
//Payment function
const pay = async () => {
//First we create token for the payment
const resToken = await createToken({...card,type:'Card'})
//Then we create data for the payment , like amount and currency
const payData = {
amount : bookPrice * 100,
currency : "eur",
}
console.log(payData)
//If credit card fields are correct fil out ,then continue to further confirmations
if(Object.keys(resToken) == "token"){
//Request to check the success of the payment
await axios.post(URL+"/createPayment",
{...payData}).then((response)=>{
const { confirmPaymentIntent } = confirmPayment(response.data.paymentIntent,{paymentMethodType : 'Card'})
//If confirm is true then update the book table in Bought Column
if(Object.keys(response.data).length > 1){
Alert.alert("Success payment")
//Request to inform the table that this book is bought
axios.post( URL+"/bookBuy",
{
bookCheckID : bookID,
userBoughtItID : global.id
}).catch((error)=>{
console.log("Axios request failed to buy the book")
})
//End of second Axios request
}
else
{
console.log("Token Error ,maybe card credits is wrong")
Alert.alert("Error in payment,maybe card credits are wrong?")
}
}).catch((error)=>{
console.log("Axios request for payment failed")
})
//End of first Axios request
}
else{
Alert.alert("Card credentials are not Valid")
}
}
return (
//Stripe public key provider
<StripeProvider
publishableKey = "pk_test_51MAWjfI5vsjFWvGhrr5n2mAujexURegEgW4ujlSPpois9Em7FBzHrEkuv5zkeRjck8CeLBAcI761eVqgWQ3mL6EX00oSp0WeB6"
merchantIdentifier = "merchant.com.{{E-LIBRARY}}"
urlScheme = "your-url-scheme"
>
<KeyboardAvoidingView
style={{ height: Platform.OS ==='ios' ? Dimensions.get('window').height * 1 : Dimensions.get('window').height * 1}}
behavior={(Platform.OS === 'ios') ? 'position' : "position"}
enabled
keyboardVerticalOffset={Platform.select({ ios: -50, android: -50 })}
>
<View style = {styles.container}>
{/* Header */}
<Header />
{/* Container */}
<View style={styles.container}>
<View style = {styles.viewContainerForInfos}>
<Text style = {styles.bookText}>{bookItem.title}</Text>
<View style = {styles.imageView}>
<Image
style = {{width:'30%',height:'60%',borderRadius:22,position:'relative',resizeMode:'contain'}}
source = {{uri :'data:image/png;base64,' + Buffer.from(bookImage.data,'hex').toString('base64')}}
/>
<AntDesign name="checkcircleo" size={24} color="white" style = {{}} />
</View>
</View>
<View style = {styles.viewForCardinfo}>
<Text style = {styles.creditText}>Credit Card Informations</Text>
<FontAwesome5 name="id-card-alt" size={30} color="black" />
</View>
<View style = {{alignItems:'center',width:'100%',height:'100%'}}>
{/* Card component from Stripe */}
<CardField
postalCodeEnabled={true}
placeholder={{
number: '4242 4242 4242 4242',
}}
cardStyle={{
backgroundColor: '#FFFFFF',
textColor: '#000000',
borderWidth:2,
borderRadius:15
}}
style={{
width: '80%',
height: '8%',
marginVertical: '15%',
}}
onCardChange={(cardDetails) => {
setCard(cardDetails);
}}
/>
{/* Pressable in order for the client to pay */}
<Pressable style = {styles.pressable} onPress = {() => {pay()}}>
<Text style = {styles.pressableText}>Buy</Text>
</Pressable>
</View>
</View>
</View>
</KeyboardAvoidingView>
</StripeProvider>
)
}
Header
//React imports
import React, { useState } from 'react';
import { StyleSheet, Text, View, Pressable, Modal, Platform} from 'react-native';
import { useNavigation } from '#react-navigation/native';
//Icon Imports
import { SimpleLineIcons } from '#expo/vector-icons';
//Icons inside header modal
import { AntDesign } from '#expo/vector-icons';
import { Feather } from '#expo/vector-icons';
export default function Header() {
//Use of navigation Hook
const navigation = useNavigation();
//Modal Constructor
const [modalVisible,setModalVisible] = useState(false);
return (
<View style = {styles.Container}>
{/* Modal*/}
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
setModalVisible(!modalVisible);
}}>
<View style = {styles.modalStyle}>
{/* Pressable and Text for each functionality */}
<Pressable style = {styles.pressable} onPress = { () => navigation.navigate('Home')}>
<AntDesign name="home" size={24} color="black" style = {{marginRight:'2%',marginLeft:'2%'}}/>
<Text style = {styles. textInsideModalPressables}>Home</Text>
</Pressable>
<Pressable style = {styles.pressable} onPress = { () => navigation.navigate('MyBooks')}>
<Feather name="book" size={24} color="black" style = {{marginRight:'2%',marginLeft:'2%'}}/>
<Text style = {styles. textInsideModalPressables}>My Collection</Text>
</Pressable>
<Pressable style = {styles.pressable} onPress = { () => navigation.navigate('Profile')}>
<AntDesign name="profile" size={24} color="black" style = {{marginRight:'2%',marginLeft:'2%'}}/>
<Text style = {styles. textInsideModalPressables}>Profile</Text>
</Pressable>
<Pressable style = {styles.pressable} onPress = { () => navigation.navigate('Settings')}>
<Feather name="settings" size={24} color="black" style = {{marginRight:'2%',marginLeft:'2%'}}/>
<Text style = {styles. textInsideModalPressables}>Settings</Text>
</Pressable>
<Pressable style = {styles.pressable} onPress = { () => navigation.navigate('LogInPage')}>
<AntDesign name="logout" size={24} color="black" style = {{marginRight:'2%',marginLeft:'2%'}}/>
<Text style = {styles. textInsideModalPressables}>Log Out</Text>
</Pressable>
<Pressable onPress={ () => {setModalVisible(!modalVisible)}} style = {styles.pressable}>
<AntDesign name="closecircleo" size={24} color="black" style = {{marginRight:'2%',marginLeft:'2%'}}/>
<Text style = {styles. textInsideModalPressables}>Close modal</Text>
</Pressable>
</View>
</Modal>
{/* Pressable Mechanism in order to open the Modal */}
<Pressable onPress={ () => {setModalVisible(!modalVisible)}} style = {styles.pressableMenu}>
<SimpleLineIcons style = {styles.iconMenu} name="menu" size={24} color="white" />
<Text style = {styles.menuText}>Menu</Text>
</Pressable>
<View style ={{width:'50%',alignItems:'center',justifyContent:'center'}}>
<Text style = {styles.nameText}> E-Library</Text>
</View>
</View>
);}

Flatlist item redirects to details page

I am new at react native and I am trying to make a detail page for my crypto price API.
What I need to do is when the user press on crypto he is redirected to a detail screen page where he can see charts, price etc. I have no idea what I should do next, I tried onpress() but it did not work. How can I make those flatList elements that are displayed using CryptoList when clicking on them shows detail page?
App.js
export default function App() {
const [data, setData] = useState([]);
const [selectedCoinData, setSelectedCoinData] = useState(null);
useEffect(() => {
const fetchMarketData = async () => {
const marketData = await getMarketData();
setData(marketData);
}
fetchMarketData();
}, [])
return (
<View style={styles.container}>
<View style={styles.titleWrap}>
<Text style={styles.largeTitle}>
Crypto
</Text>
<Divider width={1} style={styles.divider} />
</View>
<FlatList
keyExtractor={(item) => item.id}
data={data}
renderItem={({ item }) => (
<CryptoList
name={item.name}
symbol={item.symbol}
currentPrice={item.current_price}
priceChangePercentage={item.price_change_percentage_24h}
logoUrl={item.image}
/>
)}
/>
</View>
);
}
cryptoList.js
const CryptoList = ({ name, symbol, currentPrice, priceChangePercentage, logoUrl}) => {
const priceChangeColor = priceChangePercentage > 0 ? 'green' : 'red';
return (
<TouchableOpacity>
<View style={styles.itemWrapper}>
{/*Left side view*/}
<View style={styles.leftWrap}>
<Image source={{uri: logoUrl}} style={styles.image}/>
<View style={styles.titleWrapper}>
<Text style={styles.title}>{ name }</Text>
<Text style={styles.subtitle}>{ symbol.toUpperCase() }</Text>
</View>
</View>
{/*Right side view*/}
<View style={styles.rightWrap}>
<Text style={styles.title}>€{currentPrice.toLocaleString('de-DE', {currency: 'Eur'})}</Text>
<Text style={[styles.subtitle,{color: priceChangeColor} ]}>{priceChangePercentage.toFixed(2)}%</Text>
</View>
</View>
</TouchableOpacity>
)
}
import React, { useEffect, useState } from "react";
import { Text, View, StyleSheet, FlatList} from 'react-native';
import { Divider, useTheme } from 'react-native-elements';
import Constants from 'expo-constants';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import { HomeScreen } from './pages/homeScreen';
// You can import from local files
import CryptoList from './components/cyproList';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
import { getMarketData } from './components/cryptoApi';
const Stack = createNativeStackNavigator();
export default function App() {
const [data, setData] = useState([]);
const [selectedCoinData, setSelectedCoinData] = useState(null);
useEffect(() => {
const fetchMarketData = async () => {
const marketData = await getMarketData();
setData(marketData);
}
fetchMarketData();
}, [])
return (
<View style={styles.container}>
<View style={styles.titleWrap}>
<Text style={styles.largeTitle}>
Kriptovalūtu cenas
</Text>
<Divider width={1} style={styles.divider} />
</View>
<FlatList
keyExtractor={(item) => item.id}
data={data}
renderItem={({ item }) => (
<CryptoList
name={item.name}
symbol={item.symbol}
currentPrice={item.current_price}
priceChangePercentage={item.price_change_percentage_24h}
logoUrl={item.image}
/>
)}
/>
</View>
);
}
const styles = StyleSheet.create({
container:{
flex: 1,
backgroundColor: '#fff',
},
titleWrap:{
marginTop:50,
paddingHorizontal: 15,
},
largeTitle:{
fontSize: 22,
fontWeight: 'bold',
},
divider: {
marginTop: 10,
}
});
<!-- begin snippet: js hide: false console: true babel: false -->
<div data-snack-id="2OtINTPVy" data-snack-platform="android" data-snack-preview="true" data-snack-theme="light" style="overflow:hidden;background:#F9F9F9;border:1px solid var(--color-border);border-radius:4px;height:505px;width:100%"></div>
<script async src="https://snack.expo.dev/embed.js"></script>
your code seems incomplete. Have you tried wonPress={() => navigate(DetailsPage, {selectedCoinData})} where selectedCoinData is the details of your coin, then on details page you can retrieve the info with the params of react navigation with const route = useRoute() and use route.params.selectedCoinData
<FlatList
keyExtractor={(item) => item.id}
data={data}
renderItem={({ item }) => (
<CryptoList
name={item.name}
symbol={item.symbol}
currentPrice={item.current_price}
onPress={() => navigate(DetailsPage, {selectedCoinData})}
priceChangePercentage={item.price_change_percentage_24h}
logoUrl={item.image}
/>
)}
/>
and then in your component
const CryptoList = ({ name, symbol, currentPrice, priceChangePercentage, logoUrl, onPress}) => { return (
<TouchableOpacity onPress={onPress}>

react native recyclerlistview if state changed its scroll to top

If I change any state or change the textinput value, if it changed then its scroll to top and leave the textinput. Or If I like one product, its autoamticlly scroll to top if the array is changed. Anyone can help me ?
import React, { useState, useMemo, useEffect, forwardRef, memo } from 'react';
import { StyleSheet, Text, TextInput, View, TouchableOpacity, Image, Dimensions } from 'react-native';
import { TouchableWithoutFeedback } from 'react-native-gesture-handler';
import { RecyclerListView, LayoutProvider, DataProvider } from 'recyclerlistview';
import { useSelector, useDispatch } from 'react-redux';
import { AntDesign } from '#expo/vector-icons';
import { addAmountOnCartItem } from '../../../redux/slice/product/shopping_cart';
import faker from 'faker';
import ButtonWithoutLoader from '../../ButtonWithoutLoader';
const { width, height } = Dimensions.get('window');
const Shopping_cart_list = ({ datas, onPressSetting }) => {
const dispatch = useDispatch();
const provider = useMemo(() => {
return new DataProvider(
(r1, r2) => {
return r1 !== r2;
},
index => {
return 'id:' + index;
}
)
}, []);
const dataProvider = useMemo(() => {
return provider.cloneWithRows(datas);
}, [datas, provider]);
const [update, updateRecycler] = useState({
update: false
});
const handleChange = (e, product_id) => {
dispatch(addAmountOnCartItem({ value: e, product_id }));
updateRecycler(prevState => {
return {
update: !prevState
}
});
};
const layoutProvider = new LayoutProvider((i) => {
return dataProvider.getDataForIndex(i).type;
}, (type, dim) => {
switch(type) {
case 'NORMAL':
dim.height = 250;
dim.width = width * 0.9;
break;
default:
dim.height = 0;
dim.width = 0;
break;
}
});
const RenderData = memo(({ product_id, product_name, price, product_image, amount, username }) => {
return (
<TouchableWithoutFeedback style={{height: 250, backgroundColor: '#fff', marginBottom: 16}}>
<View style={styles.header}>
<TouchableOpacity style={styles.profile_info}>
<Image source={{uri: faker.image.avatar()}} resizeMode="contain" style={styles.profile_image} />
<Text style={styles.username}>{ username }</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => onPressSetting(product_id)}>
<AntDesign name="setting" size={24} color="#444" />
</TouchableOpacity>
</View>
<View style={styles.mainContainer}>
<Image source={{uri: product_image}} style={styles.image} />
<View>
<Text style={styles.text}>{product_name}</Text>
<Text style={styles.text}>Preis: {price}</Text>
<View style={{flexDirection: 'row', alignItems: 'center'}}>
<Text style={styles.text}>Anzahl: </Text>
<AntDesign name="minussquareo" style={{marginRight: 6}} size={24} color="black" />
<TextInput onBlur={() => handleChange(1, product_id)} value={ isNaN(amount) ? '' : amount.toString() } onChangeText={e => handleChange(e, product_id)} style={{height: 28, width: 28, borderRadius: 4, textAlign: 'center', backgroundColor: '#eee'}} />
<AntDesign name="plussquareo" style={{marginLeft: 6}} size={24} color="black" />
</View>
</View>
</View>
<View style={[styles.header, { marginTop: 4 }]}>
<ButtonWithoutLoader onPress={() => updateRecycler(prevState => !prevState)} title="Jetzt Kaufen!" width={width * 0.9} />
</View>
</TouchableWithoutFeedback>
)
});
const rowRenderer = (type, data) => {
const { product_id, product_name, price, product_image, amount, username } = data.item;
return <RenderData product_id={product_id} product_name={product_name} price={price} product_image={product_image} amount={amount} username={username} />
};
return (
<View style={{flex: 1, paddingBottom: 85}}>
<RecyclerListView
dataProvider={dataProvider}
layoutProvider={layoutProvider}
forceNonDeterministicRendering={true}
rowRenderer={rowRenderer}
style={{marginLeft: width * 0.05, marginRight: width * 0.05}}
extendedState={update}
scrollViewProps={{showsVerticalScrollIndicator: false}}
/>
</View>
)
};
Flatlist:
import React, { useState, useRef, memo, useMemo } from 'react';
import { StyleSheet, Animated, FlatList, Text, TextInput, View, TouchableOpacity, Image, Dimensions } from 'react-native';
import { TouchableWithoutFeedback } from 'react-native-gesture-handler';
import { useSelector, useDispatch } from 'react-redux';
import { useNavigation } from '#react-navigation/core';
import { AntDesign } from '#expo/vector-icons';
import { addAmountOnCartItem } from '../../../redux/slice/product/shopping_cart';
import faker from 'faker';
import ButtonWithoutLoader from '../../ButtonWithoutLoader';
const { width } = Dimensions.get('window');
const Shopping_cart = ({ datas, onPressSetting }) => {
const dispatch = useDispatch();
const navigation = useNavigation();
const [update, updateRecycler] = useState({
update: false
});
const handleChange = (e, product_id) => {
dispatch(addAmountOnCartItem({ value: e, product_id }));
updateRecycler(prevState => {
return {
update: !prevState
}
});
};
const RenderItem = memo(({ item }) => {
const { product_id, product_name, price, product_image, amount, username, size, colors, desc, selectedColor, selectedSize } = item.item;
return (
<TouchableWithoutFeedback style={{height: 300, backgroundColor: '#fff', marginBottom: 16}}>
<View style={styles.header}>
<TouchableOpacity style={styles.profile_info}>
<Image source={{uri: faker.image.avatar()}} resizeMode="contain" style={styles.profile_image} />
<Text style={styles.username}>{ username }</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => onPressSetting(product_id)}>
<AntDesign name="setting" size={24} color="#444" />
</TouchableOpacity>
</View>
<TouchableOpacity onPress={() => navigation.navigate('ProductStack', {
product_id,
desc,
price,
product_image,
username,
user_profil_image: faker.image.avatar(),
size,
colors,
})} style={styles.mainContainer}>
<Image source={{uri: product_image}} style={styles.image} />
<View>
<Text style={styles.text}>{product_name}</Text>
<Text style={styles.text}>Preis: {price}</Text>
<Text style={styles.text}>Farbe: {selectedColor}</Text>
<Text style={styles.text}>Größe: {selectedSize}</Text>
<View style={{flexDirection: 'row', alignItems: 'center'}}>
<Text style={styles.text}>Anzahl: </Text>
<AntDesign name="minussquareo" style={{marginRight: 6}} size={24} color="black" />
<TextInput onBlur={() => handleChange(1, product_id)} value={ isNaN(amount) ? '' : amount.toString() } onChangeText={e => handleChange(e, product_id)} style={{height: 28, width: 28, borderRadius: 4, textAlign: 'center', backgroundColor: '#eee'}} />
<AntDesign name="plussquareo" style={{marginLeft: 6}} size={24} color="black" />
</View>
</View>
</TouchableOpacity>
<View style={[styles.header, { marginTop: 4 }]}>
<ButtonWithoutLoader onPress={() => updateRecycler(prevState => !prevState)} title="Jetzt Kaufen!" width={width * 0.9} />
</View>
</TouchableWithoutFeedback>
);
});
return (
<FlatList
data={datas}
keyExtractor={item => item.item.product_id + Math.random(100)}
renderItem={({ item }) => <RenderItem item={item}/>}
contentContainerStyle={{justifyContent: 'center', alignItems: 'center'}}
removeClippedSubviews={true}
initialNumToRender={2}
maxToRenderPerBatch={1}
extraData={update}
updateCellsBatchingPeriod={100}
/>
);
};
........................................................................................................................................................................................
If you see the docs of RecyclerView, you will see for extendedState prop:
In some cases the data passed at row level may not contain all the info that the item depends upon, you can keep all other info outside and pass it down via this prop. Changing this object will cause everything to re-render. Make sure you don't change it often to ensure performance. Re-renders are heavy.
Based on your code you are updating this prop in button click and text change handler, this will eventually re-render your screen as per the description. So, here you would need to revise your logic to avoid unnecessary re-renders.
I recently just solved this problem in my own project so I'd be glad to help.
The main issue is that you can't have ANY UI related state in your list items. None. You must instead move all of that information to be transferred through props.
I see your only instance of that is through your TextInput. This could be difficult. So my first question would then be: do you really need RecyclerListView? Unless your list is thousands of items long, and items have a complicated/image intensive UI, I'd suggest FlatList for this project.
If you do continue to need RecyclerListView, I'd suggest making it so after a textinput is finished ('finished' as in maybe after a 3 second timer or, when they press 'submit' or something like that), you change the dataProvider's data object. Change the item at the index you need, and then resubmit it with cloneWithRows()

React Native inputText with Flatlist

I'm new to react-native. This component below should render comments posted by users, I would like to add an inputText component from react-native to allow users to post a comment, but don't know where I should place it within the code below.
import React, { useState, useEffect } from 'react';
import { useNavigation } from "#react-navigation/native";
import Icon from 'react-native-vector-icons/AntDesign';
import {
StyleSheet,
Text,
View,
TouchableOpacity,
Image,
ScrollView,
FlatList,
Button,
TextInput
} from 'react-native';
import parseDate from "../utils/parseDate";
import * as API from "../api/api"
export default function CommentList({ ride }) {
const [text, setText] = React.useState("");
const [commentsData, setComments] = useState([]);
const navigation = useNavigation();
useEffect(() => {
API.getCommentsByRideId(ride.ride_id).then((comments) => {
setComments(comments)
})
}, [ride.ride_id])
deleteComment = (comment_id) => {
// useEffect(() => {
API.deleteCommentsByCommentId(comment_id).then(() => {
const updatedComments = list.filter((item) => item.comment_id !== comment_id);
setComments(updatedComments)
})
// }, [comment_id])
}
//deletes on refresh only
addComment = (newComment, ride_id) => {
API.postCommentByRideId(newComment, ride_id).then(() => {
setComments(newComment)
})
}
return (
<FlatList
style={styles.root}
data={commentsData}
ItemSeparatorComponent={() => {
return (
<View style={styles.separator} />
)
}}
keyExtractor={(item) => {
return item.author;
}}
renderItem={(item) => {
const comment = item.item;
return (
<View style={styles.container}>
<TouchableOpacity onPress={() => navigation.navigate("UserProfile", { username: item.author })}>
{/* <Image style={styles.image} source={{ uri: comment.avatar_url }} /> */}
</TouchableOpacity>
<View style={styles.content}>
<View style={styles.contentHeader}>
<Text style={styles.name}>{comment.author}</Text>
<Text style={styles.time}>
{parseDate(comment.created_at)}
{comment.votes}
</Text>
</View>
<Text rkType='primary3 mediumLine'>{comment.body}</Text>
{/* <Text style={styles.time}> Likes: {comment.votes}</Text> */}
<TouchableOpacity onPress={() => deleteComment(comment.comment_id)}>
<Icon name="delete" size={20} color="#e33057" />
</TouchableOpacity>
</View>
</View>
);
}} />
);
}
This is the inputText I would like to add to allow users to post a comment.
<TextInput
value={text}
placeholder="write..."
onChangeText={text => setText(text)}
onSubmitEditing={() => addcomment(text, ride.ride_id)}
/>
if you want to add it at fixed position in bottom of screen you may do this
<View style={{flex : 1}}>
<Flatlist
contentContainerStyle={{paddingBottom: 50}}
.../>
<View style={{position : 'absolute', bottom : 0, width : '100%', height : 50}}>
//you input here
</View>
</View>
or if you want to add it last item of flatlist you may use ListFooterComponent
<FlatList
ListFooterComponent={<Input/>}
.../>
</FlatList>

Show user info in Profile bottom tab navigator after login successfully from Login screen?

I have a React Native project. My problem is that when login successfully from the Login screen, I navigate to the Home screen. Here I have a bottom navigator tab including Home and Profile. I want to show the user info in Profile but I don't know how to do it. Can anyone give me some ideas?
Here is my code
import React, {useState} from 'react';
import {
View,
StyleSheet,
Text,
Image,
ScrollView,
Dimensions,
TouchableOpacity,
TextInput,
Alert,
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import Account from '../component/Account';
const {width: WIDTH} = Dimensions.get('window');
const Login = (props) => {
let [email, setEmail] = useState('');
let [password, setPassword] = useState('');
let [isFocused, setIsFocused] = useState(0);
const _onPress = (index) => {
setIsFocused(index);
};
const dangnhap = (params) => {
if (email.length == 0 || password.length == 0) {
Alert.alert('Thông Báo', 'Hãy nhập đầy đủ email và mật khẩu');
return;
}
try {
fetch('http://192.168.1.10:8080/api/auth/signin', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json ; charset=utf-8',
},
body: JSON.stringify(params),
})
.then((response) => response.json())
.then((responseJson) => {
console.log(responseJson);
if (responseJson.status == 200) {
props.navigation.push('Home', email);
props.navigation.navigate('Home');
} else {
Alert.alert('Thông báo', 'Đăng nhập thất bại');
}
});
} catch (error) {
console.log(error);
}
};
return (
<ScrollView style={{backgroundColor: 'white'}}>
<View style={styles.container}>
<Image
source={require('../assets/images/login.png')}
resizeMode="center"
style={styles.image}
/>
<Text style={styles.textTitle}>Chào mừng trở lại</Text>
<Text style={styles.textBody}>Đăng nhập vào tài khoản sẵn có</Text>
<View style={{marginTop: 10}} />
<View style={styles.inputContainer}>
<Icon
name="mail"
size={25}
color="#59B7C9"
style={styles.inputIcon}
/>
<TextInput
onChangeText={(value) => setEmail(value)}
placeholder="Email"
style={[
styles.input,
{borderColor: isFocused == 1 ? '#59B7C9' : 'black'},
]}
onFocus={() => _onPress(1)}
/>
</View>
<View style={styles.inputContainer}>
<Icon
name="lock-closed"
size={25}
color="#59B7C9"
style={styles.inputIcon}
/>
<TextInput
placeholder={'Mật khẩu'}
pass={true}
onChangeText={(value) => setPassword(value)}
style={[
styles.input,
{borderColor: isFocused == 2 ? '#59B7C9' : 'black'},
]}
secureTextEntry={true}
onFocus={() => _onPress(2)}
/>
</View>
<View style={{width: '90%'}}>
<TouchableOpacity
onPress={() => props.navigation.navigate('Forgot')}
style={([styles.textBody], {alignSelf: 'flex-end'})}>
<Text style={[styles.textBody, {color: 'blue'}]}>
Quên mật khẩu?
</Text>
</TouchableOpacity>
</View>
<View style={styles.buttonContainer}>
<TouchableOpacity
style={styles.buttonLogin}
onPress={() => {
const newUser = {
Email: email,
Password: password,
};
dangnhap(newUser);
}}>
<Text style={styles.buttonText}>Đăng nhập</Text>
</TouchableOpacity>
</View>
<Text style={styles.textBody}>Hoặc kết nối với</Text>
<View style={{flexDirection: 'row'}}>
<Account color="#3b5c8f" icon="facebook" title="Facebook" />
<Account color="#ec482f" icon="google" title="Google" />
</View>
<View style={{flexDirection: 'row', marginVertical: 5}}>
<Text style={styles.textBody}>Chưa có tài khoản?</Text>
<Text
style={[styles.textBody, {color: 'blue'}]}
onPress={() => props.navigation.navigate('Signup')}>
Đăng ký
</Text>
</View>
</View>
</ScrollView>
);
};
This might help
import {AsyncStorage} from 'react-native';
if (responseJson.status == 200) {
AsyncStorage.setItem('email', 'email#email.com');
props.navigation.navigate('Home');
}
Profile.js
import { AsyncStorage } from 'react-native';
export default const Profile = props => {
const [email, setEmail] = useState('');
useEffect(() => {
retrieveData();
}, []);
const retrieveData = async () => {
const email = await AsyncStorage.getItem('email');
setEmail(email);
};
render(){
return {
<View>
<Text>{email}</Text>
</View>
}
}
}