Unable to Navigate to new screen from within FlatList - reactjs

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

Related

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

How to use react-navigation's withNavigation in typescript?

I'm trying to use react-native, react-navigation and typescript together to create an app. There are only two screens(HomeScreen and ConfigScreen) and one component(GoToConfigButton) in total, as follows.
HomeScreen
import React from "react";
import { NavigationScreenProps } from "react-navigation";
import { Text, View } from "react-native";
import GoToConfigButton from "./GoToConfigButton";
export class HomeScreen extends React.Component<NavigationScreenProps> {
render() {
return (
<View>
<Text>Click the following button to go to the config tab.</Text>
<GoToConfigButton/>
</View>
)
}
}
GoToConfigButton
import React from "react";
import { Button } from "react-native";
import { NavigationInjectedProps, withNavigation } from "react-navigation";
class GoToConfigButton extends React.Component<NavigationInjectedProps> {
render() {
return <Button onPress={this.handlePress} title="Go" />;
}
private handlePress = () => {
this.props.navigation.navigate("Config");
};
}
export default withNavigation(GoToConfigButton);
The code for ConfigScreen is not given because it's not important here. Well, actually the above code works, I can go to the config screen by clicking on the button. The problem is, Typescript thinks I should provide the navigation property to GoToConfigButton manually.
<View>
<Text>Click the following button to go to the config tab.</Text>
<GoToConfigButton/> <-- Property "navigation" is missing.
</View>
How can I tell Typescript that the navigation property is given automatically by react-navigation?
You were just missing Partial<> interface wrapping your NavigationInjectedProps as it is described in this pull request where this issue was fixed.
import React from "react";
import { Button } from "react-native";
import { NavigationInjectedProps, withNavigation } from "react-navigation";
class GoToConfigButton extends React.Component<Partial<NavigationInjectedProps>> {
render() {
return <Button onPress={this.handlePress} title="Go" />;
}
private handlePress = () => {
this.props.navigation.navigate("Config");
};
}
export default withNavigation(GoToConfigButton);
Tested with #types/react-navigation >= 2.13.0
import styles from "./styles";
import React, { PureComponent } from "react";
import { Button } from "react-native-elements";
import {
DrawerItems,
NavigationInjectedProps,
SafeAreaView,
withNavigation
} from "react-navigation";
class BurgerMenu extends PureComponent<NavigationInjectedProps> {
render() {
return (
<SafeAreaView style={styles.container} >
<Button
icon={{ name: "md-log-out", type: "ionicon" }}
title={loginStrings.logOut}
iconContainerStyle={styles.icon}
buttonStyle={styles.button}
titleStyle={styles.title}
onPress={() => this.props.navigation.navigate("LoginScreen")}
/>
</SafeAreaView>
);
}
}
export default withNavigation(BurgerMenu);

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>
);
}
}

How to hide status bar (react native/iOS)?

Just starting out learning React Native. Going through examples on the official site. I did the Hello World example and the status bar is overlapping the text. How can I hide the status bar?
import React, { Component } from 'react';
import { AppRegistry, Text } from 'react-native';
class HelloWorldApp extends Component {
render() {
return (
<Text>Hello world!</Text>
);
}
}
AppRegistry.registerComponent('HelloWorldApp', () => HelloWorldApp);
Thanks
You can use the StatusBar component.
import React, { Component } from 'react';
import { AppRegistry, StatusBar, Text, View } from 'react-native';
class HelloWorldApp extends Component {
render() {
return (
<View>
<StatusBar hidden={true} />
<Text>Hello world!</Text>
</View>
);
}
}
AppRegistry.registerComponent('HelloWorldApp', () => HelloWorldApp);

Resources