I am new in react native, making a basic app that will find no of cases of corona in every country
so i have made 2 component both on separate file. how to switch from child to child component ?
Now i want to switch between them when i click on a button using stack navigator
App.js
import 'react-native-gesture-handler';
import React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import Splash from './scenes/splash';
import Corona from './scenes/corona';
const Stack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Splash">
<Stack.Screen name="Splash" component={Splash} />
<Stack.Screen name="Corona" component={Corona} />
</Stack.Navigator>
</NavigationContainer>
);
}
splash.js
import React from 'react'
import { StyleSheet, Text, View, Image, Button} from 'react-native';
export default function splash({navigation}) {
return (
<View style={styles.container}>
<Image
source={require('../assets/corona.jpg')}
resizeMode="cover" style={styles.img} />
<Text style={styles.txt}>
Track the current status {"\n"}
of the COVID-19 and{"\n"}
stay up to date.</Text>
<Text
style={styles.btn}
onPress={() => this.props.navigation.navigate('Corona')}
>Continue</Text>
</View>
)
}
corona.js (navigate to here)
import React from 'react'
import { StyleSheet, Text, View, Image, Button} from 'react-native';
export default function corona({navigation}) {
return (
<div>
<View>
<Text>Hello next screen</Text>
</View>
</div>
)
}
In splash.js
change
<Text style={styles.btn}
onPress={() => this.props.navigation.navigate('Corona')}>Continue</Text>
to
<Text style={styles.btn}
onPress={() => navigation.navigate('Corona')}>Continue</Text>
And in corona.js
Remove <div> tags in return, react-native doesn't support div tags
Hope this helps!
Related
I'm learning how to build mobile applications with React Native and I'm following a React native course by Programming with Mosh. However, I ran into a problem where I can't get my program to allow me to swipe left to delete a list item. Swiping left should open up a red square.
I have tried reading the documentation, googling answers and watching youtube videos, but I have made 0 progress :(.
Here's my code for the ListItem component:
import React from 'react';
import {View, StyleSheet, Image, TouchableHighlight } from 'react-native';
import Swipeable from 'react-native-gesture-handler/Swipeable';
import colors from '../config/colors';
import AppText from './AppText';
function ListItem({title, subTitle, image, onPress, renderRightActions}) {
return (
<Swipeable renderRightActions={renderRightActions}>
<TouchableHighlight
underlayColor={colors.lightGrey}
onPress={onPress}>
<View style={styles.container}>
<Image style={styles.image} source={image} />
<View style={styles.textContainer}>
<AppText style={styles.title}>{title}</AppText>
<AppText style={styles.subTitle}>{subTitle}</AppText>
</View>
</View>
</TouchableHighlight>
</Swipeable>
);
}
and here is the code for when I actually use it:
import React from 'react';
import {StyleSheet, FlatList} from 'react-native';
import ListItem from '../components/ListItem';
import Screen from '../components/Screen';
import ListItemSeperator from '../components/ListItemSeperator';
import ListItemDeleteAction from '../components/ListItemDeleteAction';
function MessagesScreen(props) {
return (
<Screen>
<FlatList
data={messages}
keyExtractor={message => message.id.toString()}
renderItem={({item}) =>
<ListItem
title={item.title}
subTitle={item.description}
image={item.image}
onPress={() => console.log('message selected', item)}
renderRightActions={ListItemDeleteAction}/>
}
ItemSeparatorComponent={ListItemSeperator}
/>
</Screen>
Where the renderRightActions={ListItemDeleteAction} is just another component which holds a View with some style:
function ListItemDeleteAction(props) {
return (
<View style={styles.container}></View>
);
}
Any help would be highly appreciated, Thank you in advance!
The answer was that I needed to use GestureHandlerRootView to wrap everything!
import React from 'react';
import {View, StyleSheet, Image, TouchableHighlight } from 'react-native';
import Swipeable from 'react-native-gesture-handler/Swipeable';
import {GestureHandlerRootView} from 'react-native-gesture-handler';
import colors from '../config/colors';
import AppText from './AppText';
function ListItem({title, subTitle, image, onPress, renderRightActions}) {
return (
<GestureHandlerRootView>
<Swipeable renderRightActions={renderRightActions}>
<TouchableHighlight
underlayColor={colors.lightGrey}
onPress={onPress}>
<View style={styles.container}>
<Image style={styles.image} source={image} />
<View style={styles.textContainer}>
<AppText style={styles.title}>{title}</AppText>
<AppText style={styles.subTitle}>{subTitle}</AppText>
</View>
</View>
</TouchableHighlight>
</Swipeable>
</GestureHandlerRootView>
);
}
Now the component works on android.
How do I get my app to make use of the Android back button or onPress of a button?
My relevant packages:
"react": "16.13.1",
"react-native": "0.63.4",
"react-navigation": "^4.4.4",
"react-navigation-stack": "^2.10.4"
App.js
import React from "react";
import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import incomingCallScreen from "./screens/incomingCall/incomingCallScreen";
import bookingScreen from "./screens/booking/bookingScreen";
const switchNavigator = createSwitchNavigator({
Loading: LoadingScreen,
Splash: splashScreen,
mainFlow: createStackNavigator({
IncomingCall: incomingCallScreen,
Booking: bookingScreen
}),
},
{
initialRouteName: 'Loading',
},
);
const App = createAppContainer(switchNavigator);
export default () => {
return (
<App />
);
};
Then in my BookingScreen, when i click a button, it slides right to the IncomingCall screen, BUT i cant use the back button no Android or the Decline button to slide back. Or go back at all.
My Booking.js screen:
import React, { Component, useEffect } from "react";
import { SafeAreaView, StatusBar, View, Text, StyleSheet, Dimensions, Image, ScrollView, TouchableOpacity } from "react-native";
import { withNavigation } from "react-navigation";
function BookingScreen(props) {
const today = () => {
return (
<View style={{ flexDirection: 'row', }}>
<MaterialIcon
name="call"
size={20}
color={Colors.primaryColor}
onPress={() => props.navigation.push('IncomingCall')}
style={{ alignSelf: 'flex-end', marginLeft: Sizes.fixPadding }}
/>
</View>
)
}
}
export default withNavigation(BookingScreen);
And then in the IncomingCall.js screen:
import React, {Component, useEffect, useState} from 'react';
import {View, Text, StyleSheet, ImageBackground, BackHandler, Pressable} from 'react-native';
import { withNavigation } from "react-navigation";;
import { TransitionPresets } from 'react-navigation-stack';
function IncomingCallScreen(props) {
const onDecline = () => {
navigation.goBack();
return true;
};
return (
<View style={styles.row}>
{/* Decline Button */}
<Pressable onPress={onDecline} style={styles.iconContainer}>
<View style={styles.iconButtonContainer}>
<Feather name="x" color="white" size={40} />
</View>
<Text style={styles.iconText}>Decline</Text>
</Pressable>
)
}
IncomingCallScreen.navigationOptions = () => {
return {
header: () => null,
...TransitionPresets.SlideFromRightIOS,
}
}
export default withNavigation(IncomingCallScreen);
Instead of using navigation.push('IncomingCall') like you are, instead use navigation.navigate('IncomingCall'). This will push the screen onto the stack of screens, you do not have to do it manually. Additionally, every time a user wants to go back a screen, you should use navigation.goBack(), which I see you already are. This should allow Android users to user the physical buttons on their devices.
I am trying to build an app with 5 screens , this is my code.
++ ADDED APP.JS
// ./App.js
import React from "react";
import { NavigationContainer } from "#react-navigation/native";
import { MainStackNavigator } from "./Screens/StackNavigator";
import DrawerNavigator from "./Screens/DrawerNavigator";
const App = () => {
return (
<NavigationContainer>
<DrawerNavigator />
</NavigationContainer>
);
}
export default App
*HOMESCREEN.JS*
import React from "react";
import { View, Button, Text, StyleSheet,Image } from "react-native";
const Home = ({navigation}) => {
return (
<View style = {styles.firstPage}>
<View style = {styles.topHeader}><Text style={{fontSize:30}}>WORLD GUIDE</Text></View>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Image
style={styles.tinyLogo}
source={require('../images/curvedArrow.png')}
/>
<Text> SLIDE RIGHT TO START EXPLORE !</Text>
</View>
</View>
);
};
*StackNavigator.JS*
import React from "react";
import { createStackNavigator } from "#react-navigation/stack";
import Home from "./HomeScreen";
import Fransa from "./FransaScreen";
import FransaGezi from"./FransaGezi";
const Stack = createStackNavigator();
const MainStackNavigator = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Page1-Trav" component={FransaGezi}/>
</Stack.Navigator>
);
}
const FransaStackNavigator = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Fransa" component={Fransa} />
</Stack.Navigator>
);
}
export { MainStackNavigator, FransaStackNavigator};
*FransaScreen.JS*
import React from "react";
import { View, StyleSheet, Text, Image,TouchableOpacity} from "react-native";
import Home from './HomeScreen'
import FransaGezi from './FransaGezi'
const Fransa = ({navigation}) => {
return (
<View style = {styles.firstPage}>
<View style = {styles.sectopHeader}>
<Image
style={styles.bigImage}
source={require('../images/eskis.jpg')}
/>
</View>
<View style = {styles.botHeader}>
<View style= {styles.firstBoxTop}>
<View style = {styles.firstBox}>
<TouchableOpacity onPress={() =>
navigation.navigate(FransaGezi)
}>
<Image source={require('../images/gezi.png')} style = {styles.ImageClass} />
</TouchableOpacity>
</View>
<View style = {styles.secBox}>
<TouchableOpacity>
<Image source={require('../images/food.png')} style = {styles.ImageClass} />
</TouchableOpacity>
</View>
</View>
<View style= {styles.firstBoxBot}>
<View style = {styles.firstBox}>
<TouchableOpacity>
<Image source={require('../images/para.png')} style = {styles.ImageClass} />
</TouchableOpacity>
</View>
<View style = {styles.secBox}>
<TouchableOpacity>
<Image source={require('../images/popmekan.png')} style = {styles.ImageClass} />
</TouchableOpacity>
</View>
</View>
</View>
</View>
);
};
*DrawerNavigator.JS*
import React from "react";
import { createDrawerNavigator } from "#react-navigation/drawer";
import { FransaStackNavigator } from "./StackNavigator";
import Home from "./HomeScreen";
import FransaGezi from "./FransaGezi";
import Fransa from "./FransaScreen";
import { StackActions } from "#react-navigation/native";
const Drawer = createDrawerNavigator();
const DrawerNavigator = () => {
return (
<Drawer.Navigator>
<Drawer.Screen name="Home" component={Home} />
<Drawer.Screen name="Fransa" component={FransaStackNavigator} />
</Drawer.Navigator>
);
}
export default DrawerNavigator;
*FransaGezi.JS*
import React from "react";
import { View, Button, Text, StyleSheet,Image } from "react-native";
const FransaGezi = ({}) => {
return (
<View style = {styles.firstPage}>
<View style = {styles.topHeader}><Text style={{fontSize:30}}>NOLUR ÇALIŞ</Text></View>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Image
style={styles.tinyLogo}
source={require('../images/curvedArrow.png')}
/>
<Text> PLEASE WORK !</Text>
</View>
</View>
);
};
Drawer is working without problem, when I click "Fransa" going related page. But when I click first image in FransaScreen
<TouchableOpacity onPress={() =>
navigation.navigate(FransaGezi)
}>
I get this error message >>>
The action 'Navigate' with payload undefined was not handled by any navigator.
I know that I am missing some part about StackNavigator screen but when I change it like navigation.navigate(Home) it sends me Home page.
Waiting for your helps thanks a lot :)
When dealing with routes in React Native, there are some things you have to put in mind. First of all the route types. In your case you are using StackRoutes, so a basic structure for that would be:
A Routes file
import 'react-native-gesture-handler'
import React from 'react'
import { NavigationContainer } from '#react-navigation/native'
import { createStackNavigator } from '#react-navigation/stack'
import { Home } from './pages/Home'
import { Dashboard } from './pages/Dashboard'
import { Details } from './pages/Details'
const AppStack = createStackNavigator()
export const Routes = () => {
return (
<NavigationContainer>
<AppStack.Navigator headerMode='none'>
<AppStack.Screen name='Home' component={Home} />
<AppStack.Screen name='Dashboard' component={Dashboard} />
<AppStack.Screen name='Details' component={Details} />
</AppStack.Navigator>
</NavigationContainer>
)
}
In your app, I can see that you have routes with nested routes. In that case you can simply change your component at the AppStack.Screen, and put your routes there. Example:
import DrawerNavigator from 'yout path here'
import FransaGezi from 'your path here too'
// If this is the main Routes component, you should decide what types of navigation you'll use. In this case, let's use a Stack
const AppStack = createStackNavigator()
const Routes = () => {
return(
<NavigationContainer>
<AppStack.Navigator>
<AppStack.Screen name='Some cool name' component={//here you can put a single component or another routes component, such as DrawerNavigator} />
</Appstack.Navigator>
</NavigationContainer>
)
To navigate between routes you can simply do that
//import this hook in a page you want to navigate
import { useNavigation } from '#react-navigation/native'
//you can then use it in your component
const MyComponent = () => {
const navigation = useNavigation()
return (
<Something onClick={() => navigation.navigate('here you need to put the name prop that you provided in your AppStack.Screen, for example, "Some cool name" as specified up in the Routes)} />
)
}
Plus! If I didn't help you, here's a link to React Navigation. Your doubts will surely be answered there :) React Navigation
I'm using the NativeBase (and especially the NativeBaseSink template). All my routes are defined in the App.js like this :
App.js
import { Platform } from "react-native";
import { Root } from "native-base";
import { StackNavigator, TabNavigator } from "react-navigation";
import Drawer from "./Drawer";
import Homepage from "./main_scenes/main";
import Splashscreen from "./main_scenes/home/";
import LoginScene from "./main_scenes/home/login/";
import RegisterScene from "./main_scenes/home/register/";
import InsertPhoneCode from "./main_scenes/home/pin/";
import MyResults from "./main_scenes/results/";
import MyMap from "./main_scenes/results/map/";
import UserDetails from "./main_scenes/profile/";
import MyResultsByDistance from "./main_scenes/results/Distance"
import MyResultsByAvis from "./main_scenes/results/Avis"
import Test from "./main_scenes/tab"
const AppNavigator = StackNavigator(
{
Drawer: { screen: Drawer },
RegisterScene: {screen : RegisterScene},
Splashscreen:{ screen : Splashscreen},
Homepage:{ screen : Homepage},
InsertPhoneCode:{screen:InsertPhoneCode},
LoginScene: {screen : LoginScene},
MyResults: {screen:MyResults},
MyMap:{screen:MyMap},
UserDetails:{screen:UserDetails},
MyResultsByDistance:{screen:MyResultsByDistance},
MyResultsByAvis:{screen:MyResultsByAvis},
},
{
initialRouteName: "Splashscreen",
headerMode: "none",
}
);
export default () =>
<Root>
<AppNavigator />
</Root>;
I'm using the Tabs functionality of Nativebase framework. Then, I have create an index.js where i've define all my tabs like this :
index.js
import React, { Component } from "react";
import {Dimensions, AppRegistry, StyleSheet,
ListView, ScrollView,View,Image,TouchableOpacity,AsyncStorage, Alert} from 'react-native';
import {
Container,
Header,
Title,
Button,
Icon,
Tabs,
Tab,
Text,
Right,
Left,
Body,
TabHeading,
Footer,
FooterTab,
} from "native-base";
import DisplayByDistance from "./Distance/";
import DisplayByAvis from "./Avis/";
import styles from "./styles";
import { StackNavigator } from 'react-navigation';
export default class ConfigTab extends Component {
constructor(props) {
super(props);
this.state = {
tab1: false,
mapRegion: null,
lastLat: null,
lastLong: null,
};
}
toggleTab1() {
this.setState({
tab1: true,
});
}
render() {
return (
<Container>
<Header hasTabs>
<Left>
<Button transparent onPress={() => this.props.navigation.goBack()}>
<Icon name="arrow-back" />
</Button>
</Left>
<Body style={{ flex: 3 }}>
<Title> Résultats</Title>
</Body>
<Right />
</Header>
<Tabs style={{ elevation: 3 }}>
<Tab
heading={
<TabHeading><Icon name="navigate" /><Text
style={styles.TabTitle}>Le plus prés</Text></TabHeading>
}
>
<DisplayByDistance />
</Tab>
<Tab heading={<TabHeading><Icon name="star-half" /><Text
style={styles.TabTitle}>Le mieux noté</Text></TabHeading>}>
<DisplayByAvis />
</Tab>
</Tabs>
<Footer>
<FooterTab>
<Button active={this.state.tab1} onPress={() => this.props.navigation.navigate("MyMap")}>
<Icon active={this.state.tab1} name="paper-plane" />
<Text>Afficher la carte</Text>
</Button>
</FooterTab>
</Footer>
</Container>
);
}
}
AppRegistry.registerComponent('ConfigTab', () => ConfigTab);
According to the files i've edited, when i press on the TabOne, it opens the right tab where the content is located in the file called Distance.js
So right now, everything works well except that the "props.navigation.navigate"is not recognized in my Distance.js file.
Here is my file
Distance.js
import React, { Component, PropTypes } from "react";
import {...} from 'react-native';
import {...} from "native-base";
import styles from "./../styles";
import { StackNavigator } from 'react-navigation';
import App from "./../../../App"
var productArray = [];
class TabOne extends Component {
constructor(props){
super(props)
var dataSource = new ListView.DataSource({rowHasChanged:(r1,r2) => r1.guid != r2.guid});
this.state={
data:[],
dataSource: dataSource.cloneWithRows(productArray),
isLoading:true,
}
this.donePressed=this.donePressed.bind(this);
};
componentDidMount()
{
this.getTheData(function(json){
productArray = json;
this.setState({
dataSource:this.state.dataSource.cloneWithRows(productArray),
isLoading:false
})
}.bind(this));
}
donePressed() {
const { navigate } = this.props.navigation;
navigate('UserDetails');
}
getTheData(callback) {
var url = "http://paradox.ma/workshop/webservices/getPOI_info.php";
fetch(url)
.then(response => response.json())
.then(json => callback(json))
.catch(error => alert("Erreur de connexion Internet") );
}
list(rowData) {
if (rowData === null) { return <View></View>; };
let VerifiedUser;
const VerifiedTest=rowData.Verified;
if (VerifiedTest==='1')
{
VerifiedUser=(
<Right>
<View style={styles.avatarBox}>
<Text numberOfLines={2}><Icon name="verified" size={30} color="green" /></Text>
<Text>Profil vérifié</Text>
</View>
</Right>
)}
return (
<ListItem thumbnail
onPress={() => this.donePressed().bind(this)}
>
<Left>
<View style={styles.avatarBox}>
<Thumbnail size={55} source={{uri:rowData.Avatar}} />
<Text style={styles.avatarTitle}>{rowData.Title}</Text>
</View>
</Left>
<Body>
<Text>{rowData.Title}</Text>
<Text numberOfLines={2}><Icon name="map-marker" size={15} color="grey" /> {rowData.Address}, {rowData.City} ({rowData.Distance} km)</Text>
<Text numberOfLines={3}>{rowData.Description}</Text>
</Body>
{VerifiedUser}
</ListItem>
);
}
render(){
return(
<Container>
<View>
<TouchableOpacity onPress={() => this.donePressed().bind(this)}>
<Text>Test</Text>
</TouchableOpacity>
</View>
</Container>
);
}
}
export default TabOne;
My function called donePressed() works very well when i replace the this.props.navigation.navigate by alert("Hello") But once I try to navigate between screens, I have an error : Undefined is not an object...this_2.props.navigation.navigate().
I really don't know where is the problem coming from. I have tried to define the function in the constructor, no way.
Hope to find a solution.
if you want to react navigation to inject navigation prop you'll need to declare that specific Component as a Navigator scene
but I would totally suggest using React navigation's TabNavigator,
you can find here how to nest Navigators: https://reactnavigation.org/docs/intro/nesting
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
TextInput,
TouchableOpacity,
Navigator,
TouchableHighlight
} from 'react-native';
export default class calu extends Component {
constructor(props){
super(props);
this.state={f2:null, height:null,result:0};
this.compute=this.compute.bind(this);
}
compute(){
console.log('pressed');
let f1=(this.state.f1);
let f2=parseInt(this.state.f2);
this.setState({result: f1 + f2 });
}
render() {
return (
<View>
<TextInput
keyboardType='numeric' onChangeText={(text) => this.setState({f1: parseInt(text)})} placeholder='enter second number' />
<TextInput
keyboardType='numeric' onChangeText={(text) => this.setState({f2: parseInt(text)})} placeholder='enter second number' />
<Text> result: {this.state.result.toFixed(2)} </Text>
<TouchableOpacity
onPress={this.compute}>
<Text> compute </Text>
</TouchableOpacity>
</View>
);
}
}
AppRegistry.registerComponent('calu', () => calu);
I have done small app of adding two numbers and displaying result. But I want to display result in another scene using navigator, so where can I add navigator and how to pass value to another scene? Anyone please help me and share code to me.
Thank you.