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>
Related
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>
);}
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;
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}>
I am trying to clear user's value from TextInput when user click on button but ican't get it.
I am implementing this demo using Hooks in react-native.
So please help me I am new in hooks with react-native.Thank you in advanced.
import React, { useState, useEffect } from 'react';
import { StyleSheet, View, TextInput, TouchableOpacity, Text } from 'react-native';
import { RFValue } from 'react-native-responsive-fontsize';
import { heightPercentageToDP as hp, widthPercentageToDP as wp } from 'react-native-responsive-screen';
const Login = ({ navigation }) => {
const [name, setName] = useState('');
const [password, setPassword] = useState('');
/* useEffect(() => {
console.log("login screen");
setName('');
setPassword('');
}); */
function resetTextInput () {
console.log("reset TextInput");
setName(" ");
setPassword(" ");
}
return (
<View style={styles.mainContainer}>
<Text style={styles.txtTitle}>Login</Text>
<View style={{ marginTop: 80 }}>
<TextInput
placeholder={'Username'}
style={styles.txtInput}
onChangeText={(name) => { setName(name) }}
/>
<TextInput
placeholder={'Password'}
style={styles.txtInput}
secureTextEntry={true}
onChangeText={(password) => { setPassword(password) }}
/>
</View>
<TouchableOpacity style={styles.loginBtn} onPress={()=>{resetTextInput()}}>
<Text style={styles.loginBtnTxt}>Login</Text>
</TouchableOpacity>
</View>
)
}
You can set a null value:
function resetTextInput () {
console.log("reset TextInput");
setName(null);//changed this
setPassword(null);//changed this
}
and the main thing set the state value using TextInput props "value"
<View style={{ marginTop: 80 }}>
<TextInput
placeholder={'Username'}
style={styles.txtInput}
value={name} // set state to value prop
onChangeText={(name) => { setName(name) }}
/>
<TextInput
placeholder={'Password'}
style={styles.txtInput}
secureTextEntry={true}
value={password} // set state to value prop
onChangeText={(password) => { setPassword(password) }}
/>
</View>
This solution will help you.
User empty quotes when reseting values,
function resetTextInput () {
console.log("reset TextInput");
setName('');//changed this
setPassword('');//changed this
}
and give used respective state in value prop.
<TextInput
placeholder={'Password'}
style={styles.txtInput}
secureTextEntry={true}
onChangeText={(password) => { setPassword(password) }}
value={password}
/>
same for first TextInput,
I'm trying to implement a flatlist of comments alongside a textinput at the bottom. However, when I try to place the textinput in a keyboard avoiding view so that it gets pushed to the top to see the input being typed in, it doesn't go to the top and stays at the bottom. Here is my code:
render() {
return (
<KeyboardAvoidingView enabled behavior='padding' style={styles.container}>
<View style={styles.commentStyles}>
<FlatList
keyExtractor={(item) => JSON.stringify(item.date)}
data={this.props.post.comments}
renderItem={({item}) => (
<View style={[styles.row, styles.commentContainer]}>
<Image style={styles.roundImage} source={{uri: item.commenterPhoto}}/>
<View style={[styles.left]}>
<Text>{item.commenterName}</Text>
<Text style={styles.commentText}>{item.comment}</Text>
</View>
</View>
)}
/>
<TextInput
style={styles.input}
onChangeText={(comment) => this.setState({comment})}
value={this.state.comment}
returnKeyType='send'
placeholder='Add Comment'
onSubmitEditing={this.postComment}
/>
</View>
</KeyboardAvoidingView>
);
}
My container just has a flex: 1 styling applied to it. I tried reading through the documentation for KeyboardAvoidingView but found it to be very confusing. If you guys can help me in any way, would greatly appreciate it!
Give this a try.
import React, {Component} from 'react';
import {
StyleSheet,
Text,
View,
KeyboardAvoidingView,
Platform,
Dimensions,
TextInput
} from 'react-native';
const {height: fullHeight} = Dimensions.get('window');
class Comment extends Component {
constructor(props) {
super(props);
this.state = {
pageOffset: 0,
};
}
onLayout = ({
nativeEvent: {
layout: {height},
},
}) => {
const pageOffset =
fullHeight - height;
this.setState({pageOffset});
};
render() {
return (
<View style={styles.viewContainer} onLayout={this.onLayout}>
<KeyboardAvoidingView
style={styles.container}
keyboardVerticalOffset={this.state.pageOffset}
behavior={Platform.OS === 'ios' ? 'padding' : null}>
<FlatList
keyExtractor={(item) => JSON.stringify(item.date)}
data={this.props.post.comments}
renderItem={({item}) => (
<View style={[styles.row, styles.commentContainer]}>
<Image style={styles.roundImage} source={{uri: item.commenterPhoto}}/>
<View style={[styles.left]}>
<Text>{item.commenterName}</Text>
<Text style={styles.commentText}>{item.comment}</Text>
</View>
</View>
)}
/>
<TextInput
style={styles.input}
onChangeText={(comment) => this.setState({comment})}
value={this.state.comment}
returnKeyType='send'
placeholder='Add Comment'
onSubmitEditing={this.postComment}
/>
</KeyboardAvoidingView>
</View>
);
}
}
export default Comment;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'space-between',
},
viewContainer: {
flex: 1,
},
});