Opening a new page and sending a restAPI call on click of button in react Native - react-native

I am new to react native, started learning yesterday.
So, far my file structure is this:
---Assets
--- (some images)
---Screens
---WelcomeScreen.js
---Login.js
---app.js
---server.py (contains my flask API implementations)
I would like to navigate from WelcomeScreen to Login screen on clicking the login or register button inside WelcomeScreen and also send a rest API call to my backend so that I can further process the info.
app.js:
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View, SafeAreaView } from 'react-native';
import WelcomeScreen from './screens/WelcomeScreen';
export default function App() {
return (
<SafeAreaView style={styles.container}>
<WelcomeScreen />
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container:{
flex: 1,
width: "100%",
height: "100%",
}
})
WelcomeScreen.js
import React from 'react';
import { ImageBackground, StyleSheet, View, SafeAreaView, Text, Button } from 'react-native';
import Login from './Login';
function WelcomeScreen(props) {
return (
<ImageBackground
style={styles.background}
resizeMode="cover"
source={require("../assets/bg.jpg")}>
<Button
onPress={() => props.navigation.navigate(Login)} //throwing error
//TypeError: undefined is not an object (evaluating 'props.navigation.navigate')
title="Login"
color="#fc5c65"
/>
<Button
onPress={() => props.navigation.navigate(Login)} //throwing error
//TypeError: undefined is not an object (evaluating 'props.navigation.navigate')
title="Register"
color="#4ecdc4"
/>
</ImageBackground>
);
}
const styles = StyleSheet.create({
background:{
flex: 1,
justifyContent: "flex-end"
},
loginButton:{
width: "100%",
height: 70,
backgroundColor: '#fc5c65'
},
registerButton:{
width: "100%",
height: 70,
backgroundColor: '#4ecdc4'
},
})
export default WelcomeScreen;
Login.js
import React from 'react'
import { View, Text, StyleSheet } from 'react-native'
export default function Login() {
return (
<ImageBackground
style={styles.background}
resizeMode="cover"
source={require("../assets/splash.png")}>
</ImageBackground>
)
}
const styles = StyleSheet.create({
background:{
flex: 1,
justifyContent: "flex-end"
},
loginButton:{
width: "100%",
height: 70,
backgroundColor: '#fc5c65'
},
registerButton:{
width: "100%",
height: 70,
backgroundColor: '#4ecdc4'
},
})
Now, from the WelcomeScreen.js,
I want to go to the login page upon clicking login button or register button and also send a restAPI call to the backend.
How do I do this??

Navigation isn't always built in to react native. Primarily people use libraries to handle this smoothly. Based on your code, you've been following an example based on using react-navigation which you can read about here. Essentially you'll need nest all of your screens inside of special components from that library which will pipe the navigation prop through to your screen components.
In order to run the API calls, you can add those functions calls on a new line in each of the functions you are passing as the onPress prop. Alternatively, you could place a useEffect hook in your screen components to make the API call after the navigation has completed.
// in Login.js
export const Login = () => {
useEffect(() => {
callAPI()
}, []);
...
}

Related

Problem with lining up contents: react native

I'm currently having a problem with the clickable size of a reusable button which includes an icon and text. When I run this code it seems like the entire row becomes clickable when I only want the icon and text to become clickable. Does anyone know how to solve this problem? Thanks
App.js
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import IconTextButton from './components/iconTextButton';
export default function App() {
return (
<View style={styles.container}>
<Text style={{marginTop: 100}}>My First React App! Sike </Text>
<IconTextButton iconFont="ionicons" iconName="pencil" iconSize={25} text="Add Items"/>
</View>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: 'powderblue',
},
});
iconTextButton.js
import React from 'react';
import { StyleSheet, TouchableOpacity, Text, View } from 'react-native';
import Ionicon from 'react-native-vector-icons/Ionicons';
export default function IconTextButton({ iconFont, iconName, iconSize, text, onPress }) {
const getIconFont = (iconFont) => {
switch (iconFont) {
case "ionicons":
return Ionicon;
}
};
const FontIcon = getIconFont(iconFont);
return (
<TouchableOpacity onPress={onPress} style={styles(iconSize).container>
<FontIcon name={iconName} size={iconSize} style={styles(iconSize).buttonIcon}>
<Text style={styles(iconSize).buttonText}>{text}</Text>
</FontIcon>
</TouchableOpacity>
)
}
const styles = (size) => StyleSheet.create({
container: {
backgroundColor: 'pink',
},
buttonIcon: {
backgroundColor: 'yellow',
width: size,
},
buttonText: {
backgroundColor: 'green'
},
})
Along with the code I've tried, I've also tried to keep and as seperate contents whilst adding a flexDirection: 'row' inside styles.container. This keeps the contents in the same line but it still makes the whole row clickable. I've also tried putting everything in a and moving the styles.container to the component and adding a height: size into styles.container. This makes the clickable component limited however, the component is hidden underneath due to the restricted height. I have also tried simply just using instead of making a reusable const that its an input. The same thing applies.
You can wrap your Icon and Text Component in a View component and then wrap it inside a TouchableOpacity Component
Try this or do something like this :
import React from 'react';
import { StyleSheet, TouchableOpacity, Text, View } from 'react-native';
import Ionicon from 'react-native-vector-icons/Ionicons';
export default function IconTextButton({ iconFont, iconName, iconSize, text, onPress }) {
const getIconFont = (iconFont) => {
switch (iconFont) {
case "ionicons":
return Ionicon;
}
};
const FontIcon = getIconFont(iconFont);
return (
<TouchableOpacity onPress={onPress} style={styles(iconSize).container}>
<View style={styles(iconSize).iconTextContainer}>
<FontIcon name={iconName} size={iconSize} style={styles(iconSize).buttonIcon} />
<Text style={styles(iconSize).buttonText}>{text}</Text>
</View>
</TouchableOpacity>
)
}
const styles = (size) => StyleSheet.create({
container: {
backgroundColor: 'pink',
},
iconTextContainer: {
flexDirection: 'row',
alignItems: 'center',
},
buttonIcon: {
backgroundColor: 'yellow',
width: size,
},
buttonText: {
backgroundColor: 'green'
},
})

Unable to navigate using reusable card components in React Native

I have this HomeScreen file, in it I have added Card component(Dashboard & Highlights), I have Customized the Card Components with the TitleCard to reuse the styling,
In each card there is "View All" Button to navigate to its individual Screens,
When I don't use the Cards and put the entire code in home screen and Click on the View All Button on home screen then it navigates to that page, but when I use the Cards and use its props to navigate to the link provided as forwardLink props then
I get this error
"ReferenceError: Can't find variable: navigation"
Also when I add this.props.navigation.navigate('{props.forwardLink}') in TitleCard
I get this error message:
TypeError: undefined is not an object (evaluating '_this.props.navigation')
Here are the codes for each file
TitleCards
import React from 'react';
import {StyleSheet, Text, View, TouchableOpacity} from 'react-native';
const TitleCards = props => {
return (<View style={styles.textTitlesContainer}>
<Text style={styles.textTitle}>{props.leftTitle}</Text>
<TouchableOpacity
onPress={() => navigation.navigate('{props.forwardLink}')}>
<Text style={[styles.textTitle, {color: '#F483A7'}]}>
{props.rightTitle}
</Text>
</TouchableOpacity>
</View>)
};
const styles = StyleSheet.create({
textTitlesContainer: {
flex: 1,
width: '100%',
flexDirection: 'row',
justifyContent: 'space-between',
padding: 5,
},
textTitle: {
fontSize: 20,
fontWeight: '800',
color: '#fff',
},
});
export default TitleCards;
HomeScreen
import React, {Component} from 'react';
import {
SafeAreaView,
ScrollView,
StyleSheet,
} from 'react-native';
import {CustomHeader} from '../index';
import Colors from '../constants/Colors';
import DashboardCard from './DashboardCard';
import HighlightCard from './HighlightCard';
export class HomeScreen extends Component {
render() {
return (
<SafeAreaView style={{flex: 0, backgroundColor: Colors.primary}}>
<CustomHeader
title="Home"
isHome={true}
navigation={this.props.navigation}
/>
<ScrollView style={styles.container}>
<DashboardCard />
<HighlightCard />
</ScrollView>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
height:900, backgroundColor: Colors.mainBackground,
paddingTop:6,
},
});
export default HomeScreen;
HighlightCard
import React, {Component} from 'react';
import {Text, View} from 'react-native';
import {CustomHeader} from '../../index';
const HighlightCard = (prop) => {
return (
<Card>
<TitleCards leftTitle="Highlights" rightTitle="View More" forwardLink="Highlights">
</TitleCards>
<View>
<Text>News Feed</Text>
</View>
</Card>
);
};
export default HighlightCard;
const styles = StyleSheet.create({
textTitle: {
fontSize: 20,
fontWeight: '800',
color: '#fff',
},
});
When I use the HighlightCard codes directly in HomeScreen then it navigates to that page, below is that code which works if I use it directly in Home Screen
*{/* <Text style={styles.textTitle}>Highlights</Text>
<TouchableOpacity
onPress={() => this.props.navigation.navigate('Highlights')}>
<Text style={[styles.textTitle, {color: '#F483A7'}]}>View All</Text>
</TouchableOpacity> */}*
I think there is something wrong I am doing is using the props or referencing to the navigation page
I also tried creating a const for navigation
const {navigate} = this.props.navigation
this didn't worked either

unable to use React-Native-Tts giving error Native module cannot be loaded

I simply created a react-native-project using expo and added react-native-tts and tried to use the speak function but it is giving Native module cannot be null.
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
import Tts from 'react-native-tts';
export default function App() {
return (
<View style={styles.container}>
<Button
onPress = {() => {Tts.speak("Hello, world!")}}
title = "voice"
/>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
This is an expo project and react-native-tts is not made for expo. So for text to speech I need to use expo-speech or eject the project from expo.

How to add style customisation in Google Ads for React Native app?

I am using below package currently. But I am failing to add style customisation in my AdMobBanner component. Please tell if any other package might be useful for Google Ads customisation or any other Platform Ads that supports customisation.
https://www.npmjs.com/package/react-native-admob
Please click on this link to see my current O/P. I want to remove border and add labels and buttons below it. Is it possible?
import React, { PureComponent } from 'react';
import { ScrollView, StyleSheet, View } from 'react-native';
import { AdMobBanner } from 'react-native-admob';
const BannerExample = ({ style, title, children, ...props }) => (
<View {...props} style={[styles.example, style]}>
<View>{children}</View>
</View>
);
const adUnitID = 'ca-app-pub-3940256099942544/2934735716';
export default class GoogleAdsCompo extends PureComponent {
render() {
return (
<ScrollView>
<BannerExample title="Smart Banner">
<AdMobBanner
adSize="mediumRectangle"
adUnitID={adUnitID}
ref={el => (this._smartBannerExample = el)}
/>
</BannerExample>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
example: {
paddingVertical: 10,
justifyContent: 'center',
alignItems: 'center',
},
title: {
margin: 10,
fontSize: 20,
},
});

Can't find variable: Button - React Native

I am trying to create a simple app with a button in react native, but so far every time I run my code, it gives me an error saying "Can't find variable: Button". I would like to end up with my title at the top (Already done) and a button in the center of the screen, which gives an alert when touched.
I have run through several online tutorials and cannot find a solution.
Here is my code:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* #flow
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
class Project extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.Title}>
Lucas's App
</Text>
<View style={styles.buttonContainer}>
<Button
onPress={() => { Alert.alert('You tapped the button!')}}
title="Press Me"
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
Title: {
color: '#000000',
marginTop: 13,
paddingLeft:100,
paddingRight:100,
fontFamily: 'Avenir',
fontSize: 30,
},
buttonContainer: {
margin: 20
},
});
AppRegistry.registerComponent('Project', () => Project);
Thanks in advance.
You need to make sure to import the button.
You can do this by adding 'button' to your import list:
import {
AppRegistry,
StyleSheet,
Text,
View,
Alert
Button,
} from 'react-native';