Using Routing in react-native - reactjs

I have button as mentioned below and I have an another page named JobDetails on the same folder in the project. When I click on the button "next" i need to display that JobDetails page. I have added onButtonPress with alert function and it works fine. I'm not sure on how to bring the next page on clicking the button using routing.
onButtonPress(){
alert("Prem")
}
<TouchableOpacity onPress={this.onButtonPress.bind(this)} style={styles.buttonStyle} >
<Text style={styles.nextPage}>
Next
</Text>
</TouchableOpacity>

It's very simple for react-native-router-flux, just do:
import { Actions } from 'react-native-router-flux';
onButtonPress(){
Actions.JobDetails();
}
Make sure your Scene key is correct (JobDetails in your case).
<Scene key="JobDetails" component={JobDetails} />

You can achieve this using Stack Navigator from react-navigation
Installation:
npm install --save react-navigation
Example:
import React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import { StackNavigator } from 'react-navigation';
class MyHomeScreen extends React.Component {
static navigationOptions = {
title: 'Home'
}
onButtonPress(){
this.props.navigation.navigate('JobDetails'); // navigate to JobDetails screen!
}
render() {
return (
<TouchableOpacity onPress={this.onButtonPress.bind(this)} style={styles.buttonStyle} >
<Text style={styles.nextPage}>
Next
</Text>
</TouchableOpacity>
);
}
}
class JobDetailsScreen extends React.Component {
static navigationOptions = {
title: 'Job Details'
}
render() {
return (
<View>
<Text>I'm job screen!</Text>
</View>
);
}
}
const ModalStack = StackNavigator({
Home: {
screen: MyHomeScreen
},
JobDetails: {
screen: JobDetailsScreen
}
});
export default ModalStack;

Related

Hide header from old page in react-native

I'm currently developing on a react-native application and I'm stucked at something for some time.
The problem is that I have a setup like this
Home Page -> Settings Page -> Information Page
I've hidden the header on home page, made a visible header on Settings Page and what I want to do:
I want to hide the header from the settings page when I navigate to Information Page. I mean I want that the third page gets all the space from the screen.
I'll attach a snack example of what happens in my case...
Hope someone could tell me a solution.
Thank you in advance! :)
https://snack.expo.io/#sapuu_ae/example-snack-stack -> open it on android/iOS device, it won't show good on web simulator.
The problem isn't the header, it's just that your navigation setup is a bit funky. Here are two working versions which use a different navigation setup. First, we need to define our screens.
class Home extends React.Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.paragraph} onPress={() => this.props.navigation.navigate('Second')}>
Press it
</Text>
</View>
);
}
}
class Second extends React.Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.paragraph}>
Second Page
</Text>
<Text style={styles.paragraph} onPress={() => this.props.navigation.navigate('Third')}>
Press for Third Page
</Text>
</View>
);
}
}
class Third extends React.Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.paragraph}>
Third page here
</Text>
</View>
);
}
}
This one assumes that all screens are part of the same stack:
const RootStack = createStackNavigator({
Home: Home,
Second: Second,
Third : Third
});
const AppContainer = createAppContainer(RootStack);
export default class App extends React.Component {
render() {
return <AppContainer />;
}
}
This one assumes that the third screen is contained in another stack, along with the second screen.
const secondScreenStack = createStackNavigator({
Second: Second,
Third: Third
}, {
defaultNavigationOptions: {
header: null
}
});
const RootStack = createStackNavigator({
Home: Home,
Second: secondScreenStack
});
const AppContainer = createAppContainer(RootStack);
export default class App extends React.Component {
render() {
return <AppContainer />;
}
}

How to navigate other screen by declaring another class inside of the first class using react navigation

I'm currently new here on this react native, I got confuse regarding switching my screen to another screen, I don't know why my import second screen not working when i click the onpress function declared to my first screen.,
import SecondScreen from './Screens/SecondScreen';
export default class FirstScreen extends Component<Props> {
render() {
return (
<View style={styles.container}>
<Header searchBar rounded>
<Left>
<Button transparent>
<Icon name='menu'/>
</Button>
</Left>
<Body>
<Title>Pay Bills</Title>
</Body>
<Item>
<Icon name="ios-search" />
<Input placeholder="Search" />
<Icon name="ios-people" />
</Item>
<Button transparent>
<Text>Search</Text>
</Button>
</Header>
<StatusBar backgroundColor='#6633ff' barStyle='light-content' />
<Text>How much would you like to pay?</Text>
<View style={{flex:1}}>
<Image onPress={()=> this.props.navigation.navigate('SecondScreen')} source={require('./Assets/example.png')}
style={{flex:1,width:null,height:null,resizeMode:'cover'}}
/>
</View>
</View>
);
}
}
As you can see I use the onpress function to navigate second screen.
onPress={()=> this.props.navigation.navigate('SecondScreen')}
My app.js file
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* #format
* #flow
*/
import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, SafeAreaView, ScrollView, Dimensions} from 'react-native';
import {createDrawerNavigator, DrawerItems} from 'react-navigation';
//screens
import LoginScreen from './Screens/LoginScreen';
const instructions = Platform.select({
ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
android:
'Double tap R on your keyboard to reload,\n' +
'Shake or press menu button for dev menu',
});
type Props = {};
export default class App extends Component<Props> {
render() {
return (
<AppDrawerNavigator/>
);
}
}
const AppDrawerNavigator = createDrawerNavigator({
Login:LoginScreen,
});
How to move my first screen to the second screen using react navigation.
thanks.
pass the route of second screen also in react navigation
then you can navigate to second screen
You need to make some change in app.js. add createDrawerNavigator inside createStackNavigator. Add those screen into stacknavigator in which you do not want to add into drawer. In createDrawerNavigator add those screens in which you want to show in drawer.
Please check following code
import React, { Component } from "react";
import {
Platform,
StyleSheet,
Text,
View,
SafeAreaView,
ScrollView,
Dimensions
} from "react-native";
import { createStackNavigator,createDrawerNavigator DrawerItems } from "react-navigation";
//screens
import LoginScreen from "./Screens/LoginScreen";
const instructions = Platform.select({
ios: "Press Cmd+R to reload,\n" + "Cmd+D or shake for dev menu",
android:
"Double tap R on your keyboard to reload,\n" +
"Shake or press menu button for dev menu"
});
type Props = {};
export default class App extends Component<Props> {
render() {
return( <StackNav />);
}
}
const StackNav = createStackNavigator(
{
Drawer: {
screen:AppDrawerNavigator ,
navigationOptions: {
headerMode: "none",
header: null
}
},
First: {
screen: First,
navigationOptions: {
headerMode: "none",
header: null
}
},
Second: {
screen: Second,
navigationOptions: {
headerMode: "none",
header: null
}
}
},
{
initialRouteName: "Drawer"
}
);
const AppDrawerNavigator = createDrawerNavigator({
Login: { screen: LoginScreen },
})

Navigation('DrawerOpen') is not working

I am making an app following this tutorial:
I just did it exacly the same. It compiles but the button of the Drawer Menu does not work. This is the code where the button is:
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import {createBottomTabNavigator} from 'react-navigation';
import ScreenOne from './TabNavigator/ScreenOne';
import ScreenTwo from './TabNavigator/ScreenTwo';
import { Container, Header,Left,Right,Icon } from 'native-base';
export default class AppTabNavigator extends React.Component{
static navigationOptions = ({navigation}) =>{
return{
headerLeft:(
<View style={{padding:10}}>
<Icon name ="menu" style={{fontSize: 24, color : 'black'}} onPress={()=>navigation.navigate('DrawerOpen')} />
</View>
)
}
}
render(){
return(
<HomeScreenTabNavigator screenProps={{navigation: this.props.navigation}}/>
)
}
}
const HomeScreenTabNavigator = new createBottomTabNavigator({
ScreenOne:{
screen: ScreenOne,
navigationOptions:{
tabBarLabel: 'Feed'
}
},
ScreenTwo:{
screen: ScreenTwo,
navigationOptions:{
tabBarLabel: 'Feed' }
}
})
Since version 2.X of react-navigation you can't use the following code:
navigation.navigate('DrawerOpen')
But instead you need to use:
navigation.openDrawer()
See also the Drawer documentation

Unable to Navigate to new screen from within FlatList

My first page with FlatList is :
import React, { Component } from 'react';
import { View, StyleSheet, FlatList, Text, TouchableHighlight } from 'react-native';
import { StackNavigator } from 'react-navigation';
import MoreInfo from './MoreInfo';
export default class Page1 extends Component {
constructor(props){
super(props);
}
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.container}>
<FlatList
data={users}
renderItem={
({item}) =>
<TouchableHighlight onPress={() => navigate('MoreInfo', { name: 'Jane' })}>
<Text style={styles.welcome}> {item.name} </Text>
</TouchableHighlight>
}
keyExtractor={item => item.index}
>
</FlatList>
</View>
);
}
}
const App = StackNavigator({
Page1: {screen: Page1},
MoreInfo: { screen: MoreInfo },
})
I am able to get the data displayed in a FlatList without using the navigation. But when I put Navigation and click any item on the list, I get the error:
Please help. Trying this since 3 days.
My index.android.js is
import React, { Component } from 'react';
import { AppRegistry} from 'react-native';
import MyApp2 from './src/components/MyApp2';
const MyApp2 = StackNavigator({
Page1: {screen: Page1},
MoreInfo: { screen: MoreInfo },
})
AppRegistry.registerComponent('MyApp2', () => MyApp2);
And My './src/components/MyApp2' is:
import React, { Component } from 'react';
import { StyleSheet, Text, View, TextInput, ScrollView, Alert,
FlatList, ActivityIndicator, Image,TouchableOpacity } from 'react-native';
import { Container } from 'native-base';
import AppHeader from './AppHeader';
import AppBody from './AppBody';
import AppFooter from './AppFooter';
export default class MyApp2 extends Component{
render(){
return(
<Container>
<AppHeader />
<AppBody/>
<AppFooter />
</Container>
)
}
}
I further have some tabs in the AppBody and including Page1 somewhere there. How would I go about it?
It doesn't look like you're importing Page1 anywhere and it's odd that you're importing MyApp2 and then defining a const for the StackNavigator that is also called MyApp2. I cannot test this since there are other files being imported, but I believe you just need to:
fix your imports,
fix your naming conflicts,
register all of your screens with StackNavigator so they all have access to the navigation prop,
and register the StackNavigator for your AppRegistry.
Try this:
Leave ./src/components/MyApp2 as is. Then make these edits (I'll be making the assumption that MyApp2, Page1, and MoreInfo are all located in ./src/components/:
Page1 file (whatever that is named):
import React, { Component } from 'react';
import { View, StyleSheet, FlatList, Text, TouchableHighlight } from 'react-native';
export default class Page1 extends Component {
constructor(props){
super(props);
}
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.container}>
<FlatList
data={users}
renderItem={
({item}) =>
<TouchableHighlight onPress={() => navigate('MoreInfo', { name: 'Jane' })}>
<Text style={styles.welcome}> {item.name} </Text>
</TouchableHighlight>
}
keyExtractor={item => item.index}
>
</FlatList>
</View>
);
}
}
index.android.js
import React, { Component } from 'react';
import { AppRegistry} from 'react-native';
import { StackNavigator } from 'react-navigation';
// Making an assumption for where these files are located
// since it's not in the original question.
import MyApp2 from './src/components/MyApp2';
import MoreInfo from './src/components/MoreInfo';
import Page1 from './src/components/Page1';
/**
* This presumes that MyApp2 is the screen that will be loaded first.
* I don't know how you are getting to Page1, but it will be accessible
* if you navigate to it like so:
* this.props.navigation.navigate('Page1')
* Once there, the navigate() in the FlatList of Page1 should work as written.
*/
const RootNavigator = StackNavigator({
MyApp2: {screen: MyApp2},
Page1: {screen: Page1},
MoreInfo: { screen: MoreInfo },
})
AppRegistry.registerComponent('MyApp2', () => RootNavigator);
In your index.android.js file , you are using StackNavigator but you have not imported it .
use :
import { StackNavigator } from react-navigation

react-native, how to factorize code over many tabs

I use react-native to create ios and android app
I create a test app with TabNavigator working good plus a sidemenu ( the button to open it should be in the top action bar ) and floatings actions buttons (the red circle labeled FAB on the picture). All this code is new defined on first tab : app.js.
Each tab have it's own js file with code and render.
My question is :
How to get this sidemenu,action bar and floating buttons on ALL tabs without coping all the render code and js functions over all the other tabs Js files.
when i click on a tab only the green part will change
my App.js
import React, { Component } from "react";
import {...} from "react-native";
import { TabNavigator } from "react-navigation";
import Imagetest from "./Photo";
import ListFlatlist from "./ListFlatlist";
... // importing the other file for the tabs
import styles from "./css/styles";
import SideMenu from "react-native-side-menu";
import Menu from "./Menu";
class App extends Component {
constructor(props) { ... }
...
render() {
const menu = <Menu onItemSelected={this.onMenuItemSelected} />;
return (
<SideMenu
menu={menu}
isOpen={this.state.isOpen}
onChange={isOpen => this.updateMenuState(isOpen)}
>
<View style={styles.container}>
{/* my app.js content
*/}
// this is floating buttons
<ActionButton buttonColor="rgba(231,76,60,1)">
<ActionButton.Item buttonColor='#9b59b6' title="New Task" onPress={() => console.log("notes tapped!")}>
<Icon name="md-create" style={styles.actionButtonIcon} />
</ActionButton.Item>
</ActionButton>
</View>
</SideMenu>
);
}
}
const AppNavigator = TabNavigator(
{
H: { screen: App },
f: { screen: ListFlatlist },
Img: { screen: Imagetest },
B: { screen: Buttonpage },
S: { screen: ListSectionlist },
F: { screen: Fetchpage }
}
);
export default AppNavigator;
If a create new components for sidemenu, action bar and FAB I have to put them on all the tab render, not the cleanest way for me but i don't see other solution now.
I put an example repo together on Github. Thats actually all it needs:
// #flow
import React, { Component } from "react";
import { View } from "react-native";
import { StackNavigator, TabNavigator } from "react-navigation";
import ActionButton from "react-native-action-button";
import Profile from "./Profile";
import Tab1View from "./Tab1";
import Tab2View from "./Tab2";
import Tab3View from "./Tab3";
const TabView = TabNavigator({
tab1: { screen: Tab1View },
tab2: { screen: Tab2View },
tab3: { screen: Tab3View },
})
const Home = (props) => {
return (
<View style={{flex: 1}}>
<TabView navigation={props.navigation} />
<ActionButton offsetY={100} />
</View>
);
}
Home.router = TabView.router;
const StackView = StackNavigator({
home: { screen: Home },
profile: { screen: Profile },
});
export default class App extends Component {
render() {
return (
<View style={{ flex: 1 }}>
<StackView />
</View>
);
}
}

Resources