NativeBase : Navigate to a screen inside a Tab (KitchenSink) - android

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

Related

The action 'Navigate' with payload undefined was not handled by any navigator. ( REACT-NATIVE)

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

react native navigate to screen from function

I'm trying to move through screens using React Navigation, the problem lies in the nested return that i use to dynamically render a set of items and doesn't let me use an arrow function to directly navigate, so i have to implement this on a function. My question here is, how do i do that? As far as my internet research went you can only push a new screen after a dialog alert shows up, i don't want that.
I'm attaching the code:
var Dimensions = require('Dimensions');
var {width,height} = Dimensions.get('window');
import React, {Component} from 'react';
import {
View,
Text,
StyleSheet,
TouchableOpacity,
Image
} from 'react-native';
import Pie from 'react-native-pie';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import NaviBarView from './../Commons/NaviBar'
import actions from '../../Redux/actions'
class Main extends Component {
constructor(props){
super(props);
this.state={
cargando:true,
cryptoCurrencyValues:{}
}
this.onNextPress = this.onNextPress.bind(this);
this.renderItems = this.renderItems.bind(this);
}
static getDerivedStateFromProps(nextProps,prevState){
console.warn('Positivo', Object.keys(nextProps.cryptoCurrencyValues).length)
if (Object.keys(nextProps.cryptoCurrencyValues).length !== 0){
}else{
console.warn('Negativo')
}
return null;
}
onNextPress(){
**//HERE I WANT TO CALL NAVIGATE TO MOVE TO ANOTHER SCREEN**
}
componentDidMount(){
console.warn('esto una vez')
this.props.actions.getCryptoValues();
this.setState({cargando:true})
}
renderItems(){
var self = this;
return listData.map(function(cryptoValue,i){
return(
<View style={styles.itemContainer} key={i}>
<View style={{alignSelf:'center',backgroundColor:'transparent', marginLeft:10}}>
<Image source={cryptoValue.img} style={{width:width*0.095, height:height*0.050}} resizeMode={'stretch'}/>
</View>
<View style={{marginLeft:10}}>
<View style={{alignSelf:'flex-start',marginTop:15}}>
<Text style={{color:'#ffffff',fontSize:18,fontWeight: 'bold'}}>{cryptoValue.name}</Text>
</View>
<View style={{alignSelf:'flex-start',marginBottom:10}}>
<Text style={{color:'#6e6e6e',fontSize:18}}>{cryptoValue.desc}</Text>
</View>
</View>
<View style={{marginLeft:40}}>
<View style={{alignSelf:'flex-start',marginTop:15}}>
<Text style={{color:'#ffffff',fontSize:18}}>{cryptoValue.price}</Text>
</View>
<View style={{alignSelf:'flex-start',marginBottom:10}}>
<Text style={{color:'#6e6e6e',fontSize:18}}>{cryptoValue.currency}</Text>
</View>
</View>
<View style={{alignSelf:'center',backgroundColor:'transparent', marginLeft:50}}>
<TouchableOpacity onPress={() => self.onNextPress()} style={{alignSelf:'center',backgroundColor:'transparent'}}>
<Image source={require('./../../img/next.png')} style={{width:width*0.035, height:height*0.032}} resizeMode={'stretch'}/>
</TouchableOpacity>
</View>
</View>
);
});
}
render(){
return(
<View style={styles.container}>
<View>
<NaviBarView/>
</View>
<View style={styles.cardContainer}>
<View style={{marginTop:10,flexDirection: 'row',marginTop:10,marginLeft:10,alignItems:'stretch'}}>
<Image source={require('./../../img/pie-chart.png')} resizeMode={'stretch'} style={{width:width*0.095, height:height*0.055}}/>
<Text style={{fontSize:20,color:'#ffffff',fontWeight:'bold',marginLeft:15,alignSelf:'center'}}>STATUS</Text>
<TouchableOpacity style={{marginLeft:230,alignSelf:'center'}}>
<Image source={require('./../../img/reload.png')} resizeMode={'stretch'} style={{width:width*0.065, height:height*0.035}}/>
</TouchableOpacity>
</View>
<View style={{alignSelf:'flex-start',marginTop:50}}>
<Pie
radius={100}
innerRadius={97}
series={[10, 20, 30, 40]}
colors={['#f00', '#0f0', '#00f', '#ff0']}
/>
</View>
</View>
{this.renderItems()}
</View>
);
}
}
const listData = [
{_id:1,name:'Bitcoin',desc:'Billetera BTC',price:'$141,403.22',currency:'BTC: $11.673,50',img:require('./../../img/bitcoin.png')},
{_id:2,name:'Ethereum',desc:'Billetera ETH',price:'$20200,50',currency:'ETH: $863,40',img:require('./../../img/ethereum.png')},
{_id:3,name:'NEO',desc:'Billetera NEO',price:'$40.401',currency:'NEO: $118,02',img:require('./../../img/neo.png')},
];
const styles = new StyleSheet.create({
container:{
flex:1,
backgroundColor: '#0d0d0d',
flexDirection: 'column',
position:'relative',
},
cardContainer:{
backgroundColor:'#1a1a1a',
marginTop: 7,
marginBottom:7,
marginLeft:7,
marginRight:7,
height:height*0.50,
width:width,
justifyContent: 'flex-start'
},
itemContainer:{
flexDirection: 'row',
backgroundColor:'#1a1a1a',
width:width,
height:height*0.115,
marginLeft:7,
marginRight:7,
marginBottom:7,
justifyContent: 'flex-start'
},
})
function mapStateToProps (state,props) {
return {cryptoCurrencyValues: state.cryptocurrencyValues,
}
}
function mapDispatchToProps (dispatch) {
return {
actions: bindActionCreators(actions, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Main);
You can use Stack Navigator here which is very easy to navigate from one screen to another and as well as in function too...
First.
Install library :-
npm install --save react-navigation
Then use it in your class by using import :-
import {StackNavigator} from 'react-navigation';
export that class
export default Project = StackNavigator(
{
xyz: { screen: xyz },
});
After that navigating using function:-
onNextPress=()=>
{
this.props.navigation.navigate('xyz');
}
Hope.it will helps you .
Thanx!
I was not passing the navigation prop when defining my RootStack:
import React, {Component} from 'react'
import {
AppRegistry,
StyleSheet,
Text,
View,
} from 'react-native';
import createStore from './../../Redux/store';
import {StackNavigator} from 'react-navigation';
import { Provider } from 'react-redux';
import MainView from '../Main/Main';
import MainSecondLvlView from '../Main/MainSecondLvl';
import BalanceView from './../Charts/BalanceView'
import MenuView from './Menu'
const store = createStore();
const RootStack = StackNavigator({
Main: { screen: MainView },
MainSecondLvl: { screen: MainSecondLvlView},
Menu:{ screen: MenuView }
},
{
initialRouteName: 'Main',
headerMode: 'none',
});
export default class App extends Component {
render(){
return(
<Provider store={store}>
<RootStack navigation={this.props.navigation}/>
</Provider>
);
}
}

this.props.navigation is undefined when using DrawerNavigator

I'm integrating DrawerNavigator of 'react-navigation' to my project as this document. But when I run the project it always get this error when click on the Button:
TypeError: undefined is not an object (evaluating
'this.props.navigation.navigate')
And when I swipe from left to right, nothing happen, no drawer open.
I've check this.props and it's always log empty {} in console.
I tried many solutions but it's still not working.
calculator.js
export default class Calculator extends Component {
constructor(props) {
super(props);
}
static navigationOptions = {
drawerLabel: 'Calculator',
drawerIcon: ({ tintColor }) => (
<Image
source={require('./../../res/images/icon_calculator.png')}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
};
render() {
return (
<View style={styles.container}>
<View>
<Text style={styles.title}>Tip Calculator</Text>
</View>
<Button
onPress={() => this.props.navigation.navigate("SettingsScreen")}
title="Go to settings"
/>
</View>
);
}
}
module.exports = Calculator;
settings.js
export default class Settings extends Component {
constructor(props) {
super(props);
}
static navigationOptions = {
drawerLabel: 'Settings',
drawerIcon: ({ tintColor }) => (
<Image
source={require('./../../res/images/icon_settings.png')}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
};
render() {
return (
<View style={styles.container}>
<Text>Settings</Text>
<Button
onPress={() => this.props.navigation.goBack()}
title="Go back home"
/>
</View>
);
}
}
module.exports = Settings;
navigation.js
import {
DrawerNavigator
} from 'react-navigation';
import Calculator from './../components/calculator/calculator.js';
import Settings from './../components/settings/settings.js';
const RootDrawer = DrawerNavigator({
CalculatorScreen: {
path: '/',
screen: Calculator
},
SettingsScreen: {
path: '/sent',
screen: Settings
}
}, {
initialRouteName: 'CalculatorScreen',
drawerPosition: 'left'
});
export default RootDrawer;
App.js
export default class App extends Component<{}> {
render() {
return (
<Calculator/>
);
}
}
index.js
import { AppRegistry } from 'react-native';
import App from './App';
AppRegistry.registerComponent('rn_tip_calculator', () => App);
Do I have to use StackNavigator with DrawerNavigator, or am I missed something in config?
Full source code, it's only a simple example project, please have a look: https://github.com/HCMUS-IceTeaViet-SE/rn_tip_calculator
Any help will be appreciated. Thanks!
You can use dispatch api https://reactnavigation.org/docs/navigators/navigation-actions
1) import navigation actions
import { NavigationActions } from 'react-navigation'
2) dispatch navigation action:
const navigateAction = NavigationActions.navigate({
routeName: 'SettingsScreen',
params: {},
})
this.props.navigation.dispatch(navigateAction)
I'm pretty new to React-Native but sometimes this also happens to me.
I'm using Redux and stack navigator.... but here is my working example...
import { StackNavigator } from 'react-navigation'
import { Animated, Easing } from 'react-native'
import LoginScreen from '../Containers/LoginScreen'
import LaunchScreen from '../Containers/LaunchScreen'
import HomeScreen from '../Containers/HomeScreen'
import SignUpScreen from '../Containers/SignUpScreen'
import SettingsScreen from '../Containers/SettingsScreen'
import VehicleCreateScreen from '../Containers/VehicleCreateScreen'
import styles from './Styles/NavigationStyles'
// Manifest of possible screens
const PrimaryNav = StackNavigator({
LoginScreen: { screen: LoginScreen },
LaunchScreen: { screen: LaunchScreen },
HomeScreen: { screen: HomeScreen },
SignUpScreen: { screen: SignUpScreen },
SettingsScreen: { screen: SettingsScreen },
VehicleCreateScreen: { screen: VehicleCreateScreen }
}, {
// Default config for all screens
headerMode: 'none',
initialRouteName: 'LaunchScreen',
navigationOptions: {
headerStyle: styles.header
},
transitionSpec: {
duration: 0,
timing: Animated.timing,
easing: Easing.step0,
},
},
)
export default PrimaryNav
And then from a component not connected to REDUX
import React, { Component } from 'react';
import { Container, Content, List, ListItem, Icon, Text, Button, Left, Right, Badge } from 'native-base';
import { Image } from 'react-native'
import styles from './Styles/SideBarStyle';
// import backgroundImage from '../Images/vw.jpg'
const backgroundImage = require("../Images/vw.jpg");
const drawerImage = require("../Images/dirtyHandsDark.jpg");
export default class SideBar extends Component {
constructor(props) {
super(props);
}
render() {
// *********** HERE WE DECLARE AN ARRAY TO RENDER LISTS FROM. THIS COULD ALSO BE LIST OF BIKES FROM STORE.. ***********
const datas = [
{
name: "Home",
route: "HomeScreen",
icon: "settings",
bg: "#C5F442",
},
{
name: "Repair",
route: "HomeScreen",
icon: "settings",
bg: "#C5F442",
},
{
name: "My Profile",
route: "SettingsScreen",
icon: "settings",
bg: "#C5F442",
},
];
return (
<Container>
<Content bounces={false} style={{ flex: 1, backgroundColor: "#fff", top: -1 }}>
<Image source={backgroundImage} style={styles.drawerCover}>
<Image square style={styles.drawerImage} source={drawerImage} />
</Image>
<List
dataArray={datas}
renderRow={data =>
// *********** CREATE NEW LIST ITEM ON CLICK NAVIGATE TO APPROPRIATE LISTITEM.SCREEN ***********
<ListItem button noBorder onPress={() => this.props.navigation.navigate(data.route)}>
<Left>
<Icon active name={data.icon} style={{ color: "#777", fontSize: 26, width: 30 }} />
<Text style={styles.text}>
{data.name}
</Text>
</Left>
{data.types &&
<Right style={{ flex: 1 }}>
<Badge
style={{
borderRadius: 3,
height: 25,
width: 72,
backgroundColor: data.bg,
}}
>
<Text style={styles.badgeText}>{`${data.types} Types`}</Text>
</Badge>
</Right>}
</ListItem>}
/>
</Content>
</Container>
);
}
}
You can see I reference this.props.navigation.navigate no problem.
Heres my repo for reference.
https://github.com/GavinThomas1192/motoMechanicMeeKanic/tree/master/App
This happen because I don't "connect" my DrawerNavigator to my app.
There is 2 ways to achieve this:
First way: register DrawerNavigator as app root component. In index.js change:
from AppRegistry.registerComponent('rn_tip_calculator', () => App);
to AppRegistry.registerComponent('rn_tip_calculator', () => RootDrawer);
So you could delete App.js because it's useless now.
Second way: Keep register App component (in App.js) as app root component. Then put inside App component to "connect" DrawerNavigator to the app.
export default class App extends Component<{}> {
render() {
return (
<RootDrawer/>
);
}
}
The document say nothing about how to connect the navigator to the app, nothing about register component or put navigator inside root component. This drive newbie like me mad!

React Native navigation is not working

I am trying to navigate between two screen using react-native navigation https://reactnavigation.org/. It is working from index.js to EnableNotification.js but it is not working from EnableNotification.js to CreateMessage.js
EnableNotification.js
/**
* https://github.com/facebook/react-native
* #flow
*/
import React, { Component } from "react";
import { View, Text, Image, Button, StyleSheet } from "react-native";
import { StackNavigator } from "react-navigation";
import styles from "./Styles";
import * as strings from "./Strings";
import CreateMessage from "./CreateMessage";
export default class EnableNotificationScreen extends Component {
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.container}>
<Image source={require("./img/enable_notification.png")} />
<Text style={styles.textStyle}> {strings.enable_notification} </Text>
<View style={{ width: 240, marginTop: 30 }}>
<Button
title="ENABLE NOTIFICATION"
color="#FE434C"
onPress={() => navigate("CreateMessage")}
style={{ borderRadius: 40 }}
/>
</View>
<Text
style={{
textAlign: "center",
marginTop: 10
}}
>
NOT NOW
</Text>
</View>
);
}
}
const ScheduledApp = StackNavigator({
CreateMessage: {
screen: CreateMessage,
navigationOptions: {
header: {
visible: false
}
}
}
});
CreateMessage.js
import React, { Component } from "react";
import { View, Text, Image, Button, StyleSheet } from "react-native";
export default class CreateMessage extends Component {
render() {
return <View><Text>Hello World!</Text></View>;
}
}
First :
index.android.js or index.ios.js
import React, { Component } from 'react';
import { AppRegistry, Navigator } from 'react-native';
import Index from './app/Index';
import CreateMessage from './app/CreateMessage';
import EnableNotification from './app/EnableNotification';
render() {
return (
<Navigator
initialRoute={{screen: 'Index'}}
renderScene={(route, nav) => {return this.renderScene(route, nav)}}
/>
)
}
renderScene(route,nav) {
switch (route.screen) {
case "Index":
return <Index navigator={nav} />
case "EnableNotification":
return <EnableNotification navigator={nav} />
case "CreateMessage":
return <CreateMessage navigator={nav} />
}
}
After that :
index.js
goEnableNotification() {
this.props.navigator.push({ screen: 'EnableNotification' });
}
Finally :
EnableNotification.js
goCreateMessage() {
this.props.navigator.push({ screen: 'CreateMessage' });
}
If you want to go back, do a function goBack :
goBack() {
this.props.navigator.pop();
}
I hope this will help you !
This worked for me - CreateMessage component needs to be part of the navigation stack in order to navigate there through this.props.navigator.navigate(<name>)

Navigation Drawer in React-Native

I am a newbie in react-native, Dont mind if i ask a basic question, i wanted to know,
what is the step by step procedure to implement navigation drawer.
Referred Links this Link
I am not able to integrate it.
Any Demo project implementing drawer will also work.
Any help regarding this will be great.
Thankyou
Implementation of navigation drawer in react native as follows:
index.ios.js
'use strict';
import React, { AppRegistry } from 'react-native';
import App from './components/App';
AppRegistry.registerComponent('ReactNativeProject', () => App);
App.js:
'use strict'
import React, { Component } from 'react';
import { DeviceEventEmitter, Navigator, Text, TouchableOpacity, View } from 'react-native';
import Drawer from 'react-native-drawer';
import Icon from 'react-native-vector-icons/MaterialIcons';
import { EventEmitter } from 'fbemitter';
import Menu from './Menu';
import HomePage from './HomePage'
import ProfilePage from './ProfilePage'
import navigationHelper from '../helpers/navigation';
import styles from '../styles/root';
let _emitter = new EventEmitter();
class App extends Component {
componentDidMount() {
var self = this;
_emitter.addListener('openMenu', () => {
self._drawer.open();
});
_emitter.addListener('back', () => {
self._navigator.pop();
});
}
render() {
return (
<Drawer
ref={(ref) => this._drawer = ref}
type="overlay"
content={<Menu navigate={(route) => {
this._navigator.push(navigationHelper(route));
this._drawer.close()
}}/>}
tapToClose={true}
openDrawerOffset={0.2}
panCloseMask={0.2}
closedDrawerOffset={-3}
styles={{
drawer: {shadowColor: '#000000', shadowOpacity: 0.8, shadowRadius: 3},
main: {paddingLeft: 3}
}}
tweenHandler={(ratio) => ({
main: { opacity:(2-ratio)/2 }
})}>
<Navigator
ref={(ref) => this._navigator = ref}
configureScene={(route) => Navigator.SceneConfigs.FloatFromLeft}
initialRoute={{
id: 'HomePage',
title: 'HomePage',
index: 0
}}
renderScene={(route, navigator) => this._renderScene(route, navigator)}
navigationBar={
<Navigator.NavigationBar
style={styles.navBar}
routeMapper={NavigationBarRouteMapper} />
}
/>
</Drawer>
);
}
_renderScene(route, navigator) {
switch (route.id) {
case 'HomePage':
return ( <HomePage navigator={navigator}/> );
case 'ProfilePage':
return ( <ProfilePage navigator={navigator}/> );
}
}
}
const NavigationBarRouteMapper = {
LeftButton(route, navigator, index, navState) {
switch (route.id) {
case 'HomePage':
return (
<TouchableOpacity
style={styles.navBarLeftButton}
onPress={() => {_emitter.emit('openMenu')}}>
<Icon name='menu' size={25} color={'white'} />
</TouchableOpacity>
)
default:
return (
<TouchableOpacity
style={styles.navBarLeftButton}
onPress={() => {_emitter.emit('back')}}>
<Icon name='chevron-left' size={25} color={'white'} />
</TouchableOpacity>
)
}
},
RightButton(route, navigator, index, navState) {
return (
<TouchableOpacity
style={styles.navBarRightButton}>
<Icon name='more-vert' size={25} color={'white'} />
</TouchableOpacity>
)
},
Title(route, navigator, index, navState) {
return (
<Text style={[styles.navBarText, styles.navBarTitleText]}>
{route.title}
</Text>
)
}
}
export default App;
Menu.js
import React, { Component } from 'react';
import { ListView } from 'react-native';
import Button from 'react-native-button';
import styles from '../styles/menu'
var _navigate;
class Menu extends Component {
constructor(props) {
super(props);
this.state = {
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2
})
};
_navigate = this.props.navigate;
}
componentDidMount() {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(['HomePage', 'ProfilePage'])
});
}
_renderMenuItem(item) {
return(
<Button style={styles.menuItem} onPress={()=> this._onItemSelect(item)}>{item}</Button>
);
}
_onItemSelect(item) {
_navigate(item);
}
render() {
return (
<ListView
style={styles.container}
dataSource={this.state.dataSource}
renderRow={(item) => this._renderMenuItem(item)}
/>
);
}
}
module.exports = Menu;
ProfilePage.js
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import styles from '../styles/home'
class ProfilePage extends Component {
render(){
return (
<View style={styles.container}>
<Text>Profile Page</Text>
</View>
);
}
}
module.exports = ProfilePage;
HomePage.js
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import styles from '../styles/home'
class HomePage extends Component {
render(){
return (
<View style={styles.container}>
<Text>Home Page</Text>
</View>
);
}
}
module.exports = HomePage;
navigation.js
import React, { Platform } from 'react-native';
import _ from 'underscore';
module.exports = function (scene) {
var componentMap = {
'HomePage': {
title: 'HomePage',
id: 'HomePage'
},
'ProfilePage': {
title: 'ProfilePage',
id: 'ProfilePage'
}
}
return componentMap[scene];
}
Firstly, you need to install the react-navigation package:
npm install --save react-navigation
To make it easier and more comfortable, I put every lines of codes and comments in my App.js file
import React, { Component } from 'react';
import {
Text,
View,
StyleSheet
} from 'react-native';
import { DrawerNavigator } from 'react-navigation';
// Create HomeScreen class. When 'Home' item is clicked, it will navigate to this page
class HomeScreen extends Component {
render() {
return <Text> Home Page </Text>
}
}
// Create ProfileScreen class. When 'Profile' item is clicked, it will navigate to this page
class ProfileScreen extends Component {
render() {
return <Text> Profile Page </Text>
}
}
// Create SettingsScreen class. When 'Settings' item is clicked, it will navigate to this page
class SettingsScreen extends Component {
render() {
return <Text> Settings Page </Text>
}
}
const RootNavigation = DrawerNavigator({
Home: { screen: HomeScreen },
Profile: { screen: ProfileScreen},
Settings: { screen: SettingsScreen}
});
export default class App extends Component {
render() {
return <RootNavigation />
}
}
Here is my demo
Download source code from here (Navigation Drawer In React Native)
Create a navigation drawer menu like following:
const MyDrawerNavigator = createDrawerNavigator({
Home: {
screen: HomeScreen,
},
Settings: {
screen: SettingScreen,
},
Profile:{
screen: ProfileScreen
}
});
const MyAppdrawer = createAppContainer(MyDrawerNavigator);
Thanks!

Categories

Resources