I have created a loading screen and a Registartion screen. I would like that after 2 second my loading screen goes which basically is splash screen changes to registration screen using settimeout , but it's showing: undefined is not an object(evaluating
'_this.props')
App works perfectly till the loading screen when the set time evoke the navigation.natvigate(reg)
it throw the error
App.js
import React,{Component, useState} from "react";
import { StyleSheet, Text, View } from "react-native";
import { AppLoading } from 'expo';
import * as Font from 'expo-font';
import Registrationscreen from './screen/Registrationscreen';
import Loadingscreen from './screen/Loadingscreen';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
function HomeScreen() {
return (
<Loadingscreen/>
);
}
function Registration() {
return (
<Registrationscreen/>
);
}
const Stack = createStackNavigator();
const getFonts = () => Font.loadAsync({
'light':require('./assets/font/font.ttf')
});
function App() {
const [fontsLoaded, setFontsLoaded] = useState(false);
if(fontsLoaded){
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="home" screenOptions={{
headerShown: false
}}>
<Stack.Screen name="home" component={HomeScreen}></Stack.Screen>
<Stack.Screen name="reg" component={Registration}></Stack.Screen>
</Stack.Navigator>
</NavigationContainer>
);
} else{
return (
<AppLoading
startAsync={getFonts}
onFinish={()=> setFontsLoaded(true)}
/>
)
}
}
export default App;
LoadingScreen js
import React, { Component, useState } from 'react';
import {View, Image, Text , StyleSheet, Animated} from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { NavigationActions } from "react-navigation";
import Logo from '../assets/Logo.png';
const switchtoAuth = () =>{
this.props.navigation.navigate("reg");
};
class Loadingscreen extends Component {
state = {
LogoAnime: new Animated.Value(0),
LogoText: new Animated.Value(0),
loadingSpinner: false,
};
componentDidMount() {
const {LogoAnime, LogoText} = this.state;
Animated.parallel([
Animated.spring(LogoAnime, {
toValue: 1,
tension: 20,
friction: 1,
duration: 2000,
}).start(),
Animated.timing(LogoText, {
toValue: 1,
duration: 1,
useNativeDriver: true
}),
]).start(() => {
this.setState({
loadingSpinner: true,
});
setTimeout(switchtoAuth,1200);
});
}
render () {
return (
<View style={styles.container}>
<Animated.View
style={{
opacity: this.state.LogoAnime,
top: this.state.LogoAnime.interpolate({
inputRange: [0, 1],
outputRange: [80, 0],
}),
}}>
<Image source={Logo} />
</Animated.View>
<Text style={styles.logotext}> AL HANA </Text>
</View>
);
}
}
export default Loadingscreen;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#036BDD',
justifyContent: 'center',
alignItems: 'center',
},
logotext:{
color: '#FFFFFF',
fontFamily: 'light',
fontSize: 26,
position: "absolute",
top: 700,
fontWeight: "bold",
letterSpacing: 3,
textAlign: "center",
},
});
since your LoadingScreen component is not a screen component it will not receive the navigation prop automatically, so you need to pass through props from HomeScreen
function HomeScreen({ navigation }) {
return (
<Loadingscreen navigation={navigation}/>
);
}
and in your LoadingScreen first you need to put the switchtoAuth inside the class component without the const and then call the navigation.navigate:
class Loadingscreen extends Component {
state = {
LogoAnime: new Animated.Value(0),
LogoText: new Animated.Value(0),
loadingSpinner: false,
};
switchtoAuth = () =>{
this.props.navigation.navigate("reg");
};
// the rest of your component
First of all, in your loading screen switchtoAuth() function is outside of the LoadingScreen class that should be inside LoadingScreen class.
Since you already made LoadingScreen as a screen just add it to NavigationContainer
<NavigationContainer>
<Stack.Navigator initialRouteName="home" screenOptions={{ headerShown: false}}>
<Stack.Screen name="Splash" component={LoadingScreen}></Stack.Screen> //add LoadingScreen here
<Stack.Screen name="home" component={HomeScreen}></Stack.Screen>
<Stack.Screen name="reg" component={Registration}></Stack.Screen>
</Stack.Navigator>
</NavigationContainer>
And inside LoadingScreen componentDidMount() do this
setTimeout(() => this.props.navigation.navigate("reg"), 2000);
Related
Hello guys so I wanted to add a navigation DRAWER inside my main screen and I did not know how to nest it with the already existing stack navigator ,
this is my navigation component :
import React from "react";
import { NavigationContainer } from "#react-navigation/native";
import { createStackNavigator } from "#react-navigation/stack";
import ProductsOverviewScreen from "../screens/shop/ProductsOverviewScreen";
import ProductDetails from "../screens/shop/ProductDetailScreen";
import { HeaderButtons,Item } from "react-navigation-header-buttons";
import HeaderButton from '../components/UI/HeaderButton'
import CartScreen from "../screens/shop/CartScreen";
import OrdersScreen from "../screens/shop/OrdersScreen";
const RootNavigation=()=> {
const Stack = createStackNavigator();
const NavigationDrawerStructure = (props)=> {
//Structure for the navigatin Drawer
const toggleDrawer = () => {
//Props to open/close the drawer
props.navigationProps.toggleDrawer();
};
return (
<View style={{ flexDirection: 'row' }}>
<TouchableOpacity onPress={()=> toggleDrawer()}>
{/*Donute Button Image */}
<Image
source={{uri: 'https://raw.githubusercontent.com/AboutReact/sampleresource/master/drawerWhite.png'}}
style={{ width: 25, height: 25, marginLeft: 5 }}
/>
</TouchableOpacity>
</View>
);
}
const screenOptions ={
headerShown:true,
headerStyle: {
backgroundColor: 'white',},
headerTintColor: 'aqua',
headerTitleStyle: {
fontWeight: 'bold',
},
};
return(
<NavigationContainer>
<Stack.Navigator initialRouteName='ProductsOverview' screenOptions={screenOptions}>
<Stack.Screen name='ProductsOverview' component={ProductsOverviewScreen} options={({navigation,route})=>({title:'All Products',headerTitleStyle:{fontFamily:'open-sans-bold'},
headerRight:()=>( <HeaderButtons HeaderButtonComponent={HeaderButton}><Item title ='Cart' iconName='md-cart' onPress={()=>{navigation.navigate('CartScreen')}}/></HeaderButtons>)})}/>
<Stack.Screen name='ProductsDetail' component={ProductDetails} options={({route})=>({title:route.params.productTitle,headerTitleStyle:{fontFamily:'open-sans-bold'}})} />
<Stack.Screen name='CartScreen' component={CartScreen} options={{title:'Cart Items', headerTitleStyle:{fontFamily:'open-sans-bold'}}} />
<Stack.Screen name='OrdersScreen' component={OrdersScreen} options={{title:'Orders '}}/>
</Stack.Navigator>
</NavigationContainer>
)
}
export default RootNavigation;
and this is my app.js
import { StatusBar } from 'expo-status-bar';
import { StyleSheet } from 'react-native';
import {createStore , combineReducers} from 'redux';
import { Provider} from 'react-redux';
import AppLoading from 'expo-app-loading';
import * as Font from 'expo-font';
import productsReducer from './store/reducers/products';
import {composeWithDevTools} from 'redux-devtools-extension'
import RootNavigation from './navigation/ShopNavigation';
import cartReducer from './store/reducers/cart'
import { useState } from 'react';
import ordersReducer from './store/reducers/orders'
const rootReducer=combineReducers({
products: productsReducer,
cart: cartReducer,
orders:ordersReducer,
});
const store = createStore(rootReducer,composeWithDevTools());
const fetchFonts=()=>{
return Font.loadAsync({
'open-sans': require('./assets/fonts/OpenSans-Regular.ttf'),
'open-sans-bold': require('./assets/fonts/OpenSans-Bold.ttf')
})
}
export default function App() {
const [fontLoaded,setfontLoaded]= useState(false);
if (!fontLoaded) {
return (
<AppLoading
startAsync={fetchFonts}
onFinish={()=>setfontLoaded(true)}
onError={console.warn}
/>
);
}
return (
<Provider store={store}>
<RootNavigation />
</Provider>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
can you give me an idea how to nest them together I tried using the docs but still full of errors
and Thanks
Drawer Navigator must be a parent to both Stack and Tab navigators. With that knowledge, let we refactor our code as below:
import React from "react";
import { NavigationContainer } from "#react-navigation/native";
import { createStackNavigator } from "#react-navigation/stack";
import ProductsOverviewScreen from "../screens/shop/ProductsOverviewScreen";
import ProductDetails from "../screens/shop/ProductDetailScreen";
import { HeaderButtons, Item } from "react-navigation-header-buttons";
import HeaderButton from "../components/UI/HeaderButton";
import CartScreen from "../screens/shop/CartScreen";
import OrdersScreen from "../screens/shop/OrdersScreen";
import { createDrawerNavigator } from "#react-navigation/drawer";
const RootNavigation = () => {
const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();
const AppStack = () => (
<Stack.Navigator
initialRouteName="ProductsOverview"
screenOptions={screenOptions}
>
<Stack.Screen
name="ProductsOverview"
component={ProductsOverviewScreen}
options={({ navigation, route }) => ({
title: "All Products",
headerTitleStyle: { fontFamily: "open-sans-bold" },
headerRight: () => (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title="Cart"
iconName="md-cart"
onPress={() => {
navigation.navigate("CartScreen");
}}
/>
</HeaderButtons>
),
})}
/>
<Stack.Screen
name="ProductsDetail"
component={ProductDetails}
options={({ route }) => ({
title: route.params.productTitle,
headerTitleStyle: { fontFamily: "open-sans-bold" },
})}
/>
<Stack.Screen
name="CartScreen"
component={CartScreen}
options={{
title: "Cart Items",
headerTitleStyle: { fontFamily: "open-sans-bold" },
}}
/>
<Stack.Screen
name="OrdersScreen"
component={OrdersScreen}
options={{ title: "Orders " }}
/>
</Stack.Navigator>
);
return (
<NavigationContainer>
<Drawer.Navigator>
<Drawer.Screen name="MainStack" component={AppStack} />
</Drawer.Navigator>
</NavigationContainer>
);
};
export default RootNavigation;
I omitted component code below as can't access drawer.
const NavigationDrawerStructure = (props)=> {
//Structure for the navigatin Drawer
const toggleDrawer = () => {
//Props to open/close the drawer
props.navigationProps.toggleDrawer();
};
return (
<View style={{ flexDirection: 'row' }}>
<TouchableOpacity onPress={()=> toggleDrawer()}>
{/*Donute Button Image */}
<Image
source={{uri: 'https://raw.githubusercontent.com/AboutReact/sampleresource/master/drawerWhite.png'}}
style={{ width: 25, height: 25, marginLeft: 5 }}
/>
</TouchableOpacity>
</View>
);
}
Here a minified version of working implementation
https://snack.expo.dev/#emmbyiringiro/69dc5b
So I have my App.js which then renders a NavigationContainer with MainStack.Screen(s). I use an api to fetch some data about movies and then process it to give me a list of movieItem Objects with details about that movie. I save this moviesList object in my App.js state and want to pass this to my HomeScreen so that it can render all the movies in the moviesList object.
Please help how I can correctly get the route.params.moviesList[0].title to show.
App.js:
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import HomeScreen from './Screens/HomeScreen';
import ResultsScreen from './Screens/ResultsScreen';
import { fetchMovies } from './api';
const MainStack = createStackNavigator();
export default class App extends React.Component {
state = {
moviesList: null,
};
componentDidMount() {
this.getUsers();
}
getUsers = async () => {
const movies = await fetchMovies();
this.setState({ moviesList: movies });
console.log('===========');
console.log(this.state.moviesList);
};
render() {
return (
<NavigationContainer>
<MainStack.Navigator>
<MainStack.Screen
name="Home"
component={HomeScreen}
initialParams={this.state}
/>
<MainStack.Screen name="Results" component={ResultsScreen} />
</MainStack.Navigator>
</NavigationContainer>
);
}
}
HomeScreen.js:
import React from 'react';
import { StyleSheet, TextInput, Button, Text, View } from 'react-native';
import Row from '../Row';
export default function HomeScreen({ route, navigation }) {
console.log('ROUTE:');
console.log(route);
return (
<View style={styles.container}>
<Text style={styles.heading}>Movie Browser</Text>
<Text style={styles.heading}>{route.params.moviesList[0].title}</Text>
<TextInput style={styles.textInput} placeholder="Sreach" />
<Row props />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
},
heading: {
fontSize: 42,
padding: 20,
},
text: {
justifyContent: 'center',
fontSize: 24,
paddingBottom: 5,
},
textInput: {
borderWidth: 2,
borderColor: 'black',
minWidth: 260,
marginBottom: 20,
marginHorizontal: 20,
paddingHorizontal: 10,
paddingVertical: 5,
borderRadius: 3,
},
});
I believe the movieList array is your params. Try this in your return statement of HomeScreen.js:
<Text style={styles.heading}>{route.params[0].title}</Text>
I want to go out of top tab navigation but it unable to navigate. It's giving error The action 'NAVIGATE' with payload {"name":"LoginPage"} was not handled by any navigator.
Do you have a screen named 'LoginPage'?
If you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator
I use nesting navigation also but not work. My Screens are below
Top tab navigation screen
import * as React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createMaterialTopTabNavigator } from '#react-navigation/material-top-tabs';
import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen';
import ProfileData from './profiledata';
import ProfileLikeData from './profilelikedata';
import Fontisto from 'react-native-vector-icons/Fontisto';
const Tab = createMaterialTopTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color }) => {
let iconName;
let size;
if (route.name === 'Data') {
iconName = focused
? 'nav-icon-grid'
: 'nav-icon-grid';
size = focused
? 25
: 25;
} else if (route.name === 'Like') {
iconName = focused ? 'heart' : 'heart';
size = focused
? 20
: 20;
}
return <Fontisto name={iconName} size={size} color={color} />;
},
})}
tabBarOptions={{
activeTintColor: '#d40786',
inactiveTintColor: 'white',
showIcon:true,
showLabel:false,
indicatorStyle: {
width: 0, height: 0, elevation: 0,
},
tabStyle: { width: wp('52%'),borderRightWidth:1,borderColor:'white' },
style: { backgroundColor:'trasparent',borderTopWidth:0.5,borderColor:'white',paddingBottom:5 },
}}
>
<Tab.Screen name="Data" component={ProfileData} />
<Tab.Screen name="Like" component={ProfileLikeData} />
</Tab.Navigator>
</NavigationContainer>
);
}
profiledata.js
import React from 'react';
import { View, StyleSheet, Text,ImageBackground,TouchableOpacity,Image } from 'react-native';
import { FlatGrid } from 'react-native-super-grid';
import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen';
import { RFPercentage, RFValue } from "react-native-responsive-fontsize";
import Toast from 'react-native-simple-toast';
export default class ProfileData extends React.Component {
constructor(props) {
super(props);
this.state = {
videos:[],
loginid:'',
paused:true,
};
}
static navigationOptions = {
headerShown: false,
};
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.container}>
<FlatGrid
data={this.state.videos}
spacing={0}
renderItem={({ item }) => (
<TouchableOpacity onPress={()=>navigate('LoginPage')} style={{flex:1}}>
// some data
</TouchableOpacity>
)}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex:1,
// paddingHorizontal:wp('2%'),
backgroundColor:'black',
height: hp('100%'),
},
});
You should create another stack that has your login screen or add the login screen in the tab navigator.
for the first do something like this in your app.js
import { createStackNavigator } from '#react-navigation/stack';
import LoginScreen from './LoginScreen'; //Just import the login screen
const AuthStack = createStackNavigator();
const AuthStackScreen = () => (
<AuthStack.Navigator>
<AuthStack.Screen
name="LoginPage"
component={LoginScreen}
/>
</AuthStack.Navigator>
);
//Then in your profiledata.js;
<TouchableOpacity onPress={()=>navigate('LoginPage')} style={{flex:1}}>
// some data
</TouchableOpacity>
And for the second option just add the login screen in your tab navigator;
<Tab.Screen name="Data" component={ProfileData} />
<Tab.Screen name="Like" component={ProfileLikeData} />
<Tab.Screen name="LoginPage" component={LoginScreen} /> //Don't forget to import it
I am using react-navigation v5 right now.I have Tab navigator with 3 screens 'Home', 'Discover', 'Profile'. I need to make navigation that way i could present modal screen complitely on top of tab navigator.In docs i didn't found how to do it from Tab navigator. So i deside to nest Tab navigator inside Stack navigator. And now i have tons of issues i need to resolve:
How i can show header for each tab in Tab navigator nested inside stack.
Show modal screen from view inside 'Home'.
Since i am using typescript before v5 i was using v4 with
NavigationInjectedProps. I could access fron nested component inside 'Home' with no problems, but now i having undefined props.navigation
MainNavigator.tsx
import HomeScreen from './Home/HomeScreen';
import DiscoverScreen from './Discover/DiscoverScreen';
import ProfileScreen from './profile/ProfileScreen';
import StreamsTabScreen from './Discover/tabview/tabScreens/StreamsTabScreen';
import { Image, Platform, View } from 'react-native';
import React from 'react';
import images from 'assets/images'
import DeviceInfo from 'react-native-device-info';
import VideoPlayer from '../../library/ui/videoPlayer/VideoPlayer';
import { createStackNavigator } from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
export type TabNavigationProp = {
Home: undefined; //
Discover: undefined; // Should be here all undefined ????
Profile: undefined; //
}
export type StacknavigationProp = {
TabNavigator: undefined; // Same here ???
ModalPlayer: undefined; //
}
const Tab = createBottomTabNavigator();
const Stack = createStackNavigator();
const TabNavigator = () => {
return (
<Tab.Navigator>
<Tab.Screen name='Home' component={HomeScreen} />
<Tab.Screen name='Discover' component={DiscoverScreen} />
<Tab.Screen name='Profile' component={ProfileScreen} />
</Tab.Navigator>
);
};
const MainStackNavigator = () => {
return (
<Stack.Navigator mode='modal'>
<Stack.Screen name='TabNavigator' component={TabNavigator} options={{ headerShown: false }} />
<Stack.Screen name='ModalPlayer' component={VideoPlayer} />
</Stack.Navigator>
);
}
export default MainStackNavigator;
HomeScreen.tsx
import { View, Text, StyleSheet, ScrollView } from "react-native";
import React from "react";
import StreamsScreen from '../../streamsScreen/StreamsScreen';
import VideoplayerScreen from '../../videoplayer/VideoplayerScreen';
import { CompositeNavigationProp } from '#react-navigation/native';
import { BottomTabNavigationProp } from '#react-navigation/bottom-tabs';
import { StackNavigationProp } from '#react-navigation/stack';
import { TabNavigationProp, StacknavigationProp } from "../MainNavigator";
export type HomeScreenNavigationProps = CompositeNavigationProp<
BottomTabNavigationProp<TabNavigationProp, 'Home'>,
StackNavigationProp<StacknavigationProp>
>; // made props type from docs guide...
export default class HomeScreen extends React.Component<HomeScreenNavigationProps> {
render() {
console.log(this.props.navigate); //navigate is undefined...
return (
<View style={styles.container}>
<ScrollView style={styles.scrollView}>
<View style={{ paddingBottom: 24 }}>
<StreamsScreen navigate={this.props.navigation} /> //props.navigation does not exist
<View style={styles.separator} ></View>
<VideoplayerScreen />
</View>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
scrollView: {
flex: 1,
backgroundColor: '#0C2B33',
paddingBottom: 20,
},
separator: {
height: 1,
backgroundColor: '#3D908E'
}
});
StreamsScreen.tsx
import { View, Text, StyleSheet, Image, ActivityIndicator } from 'react-native';
import MainViewItem from '../../library/ui/MainViewItem';
import { NavigationState, SceneRendererProps, TabBar, SceneMap } from 'react-native-tab-view';
import images from 'assets/images';
import { Props as IndicatorProps } from '../../library/indicator/TabBarIndicator';
import { fetchStreamsPending, fetchStreamsRefresh } from '../../redux/actions/streamActions';
import { connect } from "react-redux";
import { RootState } from "src/redux/reducers";
import numberFormatter from "../../library/utils/numberFormatter";
import palette from 'assets/palette';
import getLanguage from '../../library/utils/isoLanguages';
import {
StreamsState,
StreamsPendingState,
StreamsErrorState,
StreamsPageOffsetState,
Stream,
StreamsRefreshState
} from '../../redux/store/types';
import { TouchableOpacity } from 'react-native-gesture-handler';
import { HomeScreenNavigationProps } from '../main/Home/HomeScreen';
interface StreamsProps {
fetchStreamsPending: typeof fetchStreamsPending;
fetchStreamsRefresh: typeof fetchStreamsRefresh;
streams: StreamsState
pending: StreamsPendingState;
error: StreamsErrorState;
pageOffset: StreamsPageOffsetState;
refresh: StreamsRefreshState;
}
type State = NavigationState<{
key: string;
}>;
type Route = {
key: string;
};
class StreamsScreen extends React.Component<StreamsProps & HomeScreenNavigationProps> { // HomeScreenNavigationProps not sure what right prop type i need here ....
...
_onPressCard = () => {
this.props.navigation.navigate('ModalPlayer'); //Property 'navigation' does not exist on type ...
this.props.navigate('ModalPlayer'); //undefined here
}
...
UPADE: I fixed the problem with navigation, i didnt implement all logic for navigation with typescript...
should do something like this:
export type TabParamList = {
Home: undefined;
Discover: undefined;
Profile: undefined;
}
export type MainStackParamList = {
TabNavigator: undefined;
Stack2Nav: undefined;
ModalPlayer: undefined;
}
export type MainStackParamList2 = {
Home: undefined;
Discover: undefined;
Profile: undefined;
}
const Tab = createBottomTabNavigator<TabParamList>();
const RootStack = createStackNavigator<MainStackParamList>();
const TabNavigator = () => {
return (
<Tab.Navigator>
<Tab.Screen name='Home' component={HomeScreen} />
<Tab.Screen name='Discover' component={DiscoverScreen} />
<Tab.Screen name='Profile' component={ProfileScreen} />
</Tab.Navigator>
);
};
const MainStackNavigator = () => {
return (
<RootStack.Navigator mode='modal'>
<RootStack.Screen name='Tab' component={Tab} options={{ headerShown: false }} />
<RootStack.Screen name='ModalPlayer' component={VideoPlayer} />
</RootStack.Navigator>
);
}
in HomeScreen.tsx :
export type HomeScreenNavigationProp = CompositeNavigationProp<
BottomTabNavigationProp<TabParamList, 'Home'>,
StackNavigationProp<MainStackParamList>
>;
type Props = {
navigation: HomeScreenNavigationProp;
};
export default class HomeScreen extends React.Component<Props> {
render() {
return (
<View style={styles.container}>
<ScrollView style={styles.scrollView}>
<View style={{ paddingBottom: 24 }}>
<StreamsScreen navigation={this.props.navigation} />
<View style={styles.separator} ></View>
<VideoplayerScreen />
</View>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
scrollView: {
flex: 1,
backgroundColor: '#0C2B33',
paddingBottom: 20,
},
separator: {
height: 1,
backgroundColor: '#3D908E'
}
});
Now what issue left is modal screen showing header even after setup mode='modal' in root stack navigator, even tho i copy pasted code from demo in docs.
Looks like the demo gif and code didn't show same behavior, i just added
{ headerShown: false } in my modal screen options:
<RootStack.Screen
name='ModalPlayer'
component={VideoPlayer}
options={{ headerShown: false }}
/>
I'm trying to create a React Native app with some basic routing.
This is my code so far:
App.js:
import React from 'react'
import { StackNavigator } from 'react-navigation'
import MainScreen from './classes/MainScreen'
const AppNavigator = StackNavigator(
{
Index: {
screen: MainScreen,
},
},
{
initialRouteName: 'Index',
headerMode: 'none'
}
);
export default () => <AppNavigator />
MainScreen.js:
import React, { Component } from 'react'
import { StyleSheet, Text, View, Button, TouchableOpacity, Image } from 'react-native'
import HomeButton from './HomeButton'
export default class MainScreen extends Component {
static navigatorOptions = {
title: 'MyApp'
}
constructor(props) {
super(props)
}
render() {
return (
<View style={styles.container}>
<Image source={require('../img/logo.png')} style={{marginBottom: 20}} />
<HomeButton text='Try me out' classType='first' />
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center'
}
})
HomeButton.js:
import React, { Component } from 'react'
import { StyleSheet, Text, View, Button, TouchableOpacity } from 'react-native'
import { StackNavigator } from 'react-navigation'
export default class HomeButton extends Component {
constructor(props) {
super(props)
}
render() {
return (
<TouchableOpacity
onPress={() => navigate('Home')}
style={[baseStyle.buttons, styles[this.props.classType].style]}
>
<Text style={baseStyle.buttonsText}>{this.props.text.toUpperCase()}</Text>
</TouchableOpacity>
)
}
}
var Dimensions = require('Dimensions')
var windowWidth = Dimensions.get('window').width;
const baseStyle = StyleSheet.create({
buttons: {
backgroundColor: '#ccc',
borderRadius: 2,
width: windowWidth * 0.8,
height: 50,
shadowOffset: {width: 0, height: 2 },
shadowOpacity: 0.26,
shadowRadius: 5,
shadowColor: '#000000',
marginTop: 5,
marginBottom: 5
},
buttonsText: {
fontSize: 20,
lineHeight: 50,
textAlign: 'center',
color: '#fff'
}
})
const styles = {
first: StyleSheet.create({
style: { backgroundColor: '#4caf50' }
})
}
Everything works fine, but when pressing the button I get
Can't find variable: navigate
I've read that I have to declare it like this:
const { navigate } = this.props.navigation
So I edited HomeButton.js and added that line at the beginning of the render function:
render() {
const { navigate } = this.props.navigation
return (
<TouchableOpacity
onPress={() => navigate('Home')}
style={[baseStyle.buttons, styles[this.props.classType].style]}
>
<Text style={baseStyle.buttonsText}>{this.props.text.toUpperCase()}</Text>
</TouchableOpacity>
)
}
Now I get:
TypeError: undefined is not an object (evaluating 'this.props.navigation.navigate')
It seems that the navigation object is not coming into the properties, but I don't understand where should I get it from.
What am I missing here?
React-navigation pass navigation prop to the screen components defined in the stack navigator.
So in your case, MainScreen can access this.props.navigation but HomeButton can't.
It should work if you pass navigation prop from MainScreen to HomeButton :
<HomeButton text='Try me out' classType='first' navigation={this.props.navigation}/>
Edit: You have to define the Homescreen in your stack navigator in order to navigate to it, your onPress={() => navigate('Home')} won't work until then.