I have a tab navigator where MyHomeScreen is the initial view.
In my Homescreen i have another component with an action to navigate to another screen but when i press it is not navigating to AnotherscreenWithouttab.
MyHomeScreen
render() {
const navigation = this.props.navigation;
const {navigate} = this.props.navigation;
return (
<Actionscreen
navigation={navigation}
/>
</View>
);
}
ActionScreen
render() {
const {navigate} = this.props.navigation;
return (
<View >
<TouchableOpacity
onPress={ () => navigate('AnotherscreenWithouttabRoute', { param1: 'Route-1' }) }
><Text>go to another screen</Text></TouchableOpacity>
</View>
);
}
TabNavigator
const DashboardTab = TabNavigator(
{
Home: {
screen: MyHomeScreen,
path: '',
},
People: {
screen: FeedScreen,
path: 'cart',
}
}
class DashboardTabComponent extends Component {
constructor(props) {
super(props);
}
render() {
const {
navigation,
screenProps
} = this.props;
return(
<DashboardTab
//navigation={navigation}
screenProps={screenProps}
//screenProps={this.state}
/>
);
}
}
router.js
import React, { Component } from 'react';
import { Text, View, ScrollView, TouchableOpacity, AsyncStorage, ActivityIndicator, Image, StyleSheet } from 'react-native';
import { DrawerNavigator, DrawerItems, DrawerView, StackNavigator, TabNavigator, Header } from 'react-navigation';
import { HomeComponent } from "./Home/HomeComponent";
import { AboutusComponent } from "./Aboutus/AboutusComponent";
import { AnotherscreenWithouttabComponent } from "./AnotherscreenWithouttab";
import FeedAndSearchTab from "./feed/FeedAndSearchTab";
import { DetailsScreen1 } from "./Details/DetailsScreen1";
import { DetailsScreen2 } from "./Details/DetailsScreen2";
import * as css from "./Styles/Styles";
import { Button, Icon } from "react-native-elements";
//
// tabs
//
const nav_tab = TabNavigator(
// route config
{
DetailsRoute1: { screen: DetailsScreen1 },
DetailsRoute2: { screen: DetailsScreen2 },
},
// navigator config
{
lazy: true, // render the tabs lazily
tabBarPosition: 'bottom', // where are the tabs shown
backBehavior: 'none', // back button doesn't take you to the initial tab
tabBarOptions: css.tabs
},
);
//
// stack
//
export const AppNavigator = (isIntroRead = false, isSignedIn = false) => {
return StackNavigator(
// route config
{
HomeRoute: { screen: HomeComponent, path: 'home', }, // this is displayed first
AboutusRoute: { screen: AboutusComponent },
AnotherscreenWithouttabRoute: { screen: AnotherscreenWithouttabComponent , path: 'appointment/schedule', },
},
// navigator config
{
//headerMode: 'none', // this removes the navigation header
initialRouteName: isIntroRead ? 'HomeRoute' : 'IntroRoute', // HomeRoute /IntroRoute AppointmentScheduleRoute
navigationOptions: ({ navigation, screenProps }) => {
return {
headerTitle: <Title
navigation={navigation}
titleName={'Doctor On Call'}
/>, // label text // headerTitle: "Hi",
...css.header, // other styling
headerLeft: <TitleAndIcon navigation={navigation} />,
headerRight: <MenuIcon
navigation={navigation}
screenProps={screenProps}
/>,
header: (props) => <ImageHeader {...props} />,
}
},
cardStyle:{backgroundColor: '#FFFFFF', shadowOpacity: 0, shadowColor: 'transparent', }
}
);
};
//export default AppNavigator;
Related
I am trying to make an authentication UI in react native and these are my files:
App.tsx
import React from 'react';
import {
ActivityIndicator,
StyleSheet,
View,
} from 'react-native';
import {
createSwitchNavigator,
createAppContainer,
} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack'
import EmailAccountLoginBlock from '../blocks/email-account-login/src/EmailAccountLoginBlock';
import { getStorageData } from '../framework/src/Utilities';
import AuthenticationStack from './Navigation/AuthStack';
import OtherStack from './Navigation/OtherStack';
class AuthLoadingScreen extends React.Component {
constructor() {
super();
this._bootstrapAsync();
}
// Fetch the token from storage then navigate to our appropriate place
_bootstrapAsync = async () => {
const userToken = await getStorageData('authToken');
// This will switch to the App screen or Auth screen and this loading
// screen will be unmounted and thrown away.
this.props.navigation.navigate(userToken ? 'App' : 'Auth');
};
// Render any loading content that you like here
render() {
return (
<View style={styles.container}>
<ActivityIndicator />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
const AppNavigator =createAppContainer(
createSwitchNavigator(
{
AuthLoading: AuthLoadingScreen,
App: OtherStack,
Auth: AuthenticationStack,
},
{
initialRouteName: 'AuthLoading',
},
));
export function App() {
return (
<AppNavigator/>
);
}
AuthStack.tsx
import React, {useState, useEffect} from 'react';
import { createStackNavigator } from 'react-navigation-stack';
import EmailAccountLoginBlock from '../../blocks/email-account-login/src/EmailAccountLoginBlock';
import EmailAccountRegistration from '../../blocks/email-account-registration/src/EmailAccountRegistration';
import ForgotPassword from '../../blocks/forgot-password/src/ForgotPassword';
import VerifyAccount from '../../blocks/user-profile-basic/src/screens/VerifyAccount/VerifyAccountPage';
const AuthStack = createStackNavigator({
EmailAccountLoginBlock: {
screen: EmailAccountLoginBlock,
navigationOptions: {title: 'EmailAccountLoginBlock', header: null},
},
EmailAccountRegistration: {
screen: EmailAccountRegistration,
navigationOptions: {title: 'CustomisableUserProfiles', header: null},
},
ForgotPassword: {
screen: ForgotPassword,
navigationOptions: {title: 'InvestMentExperience', header: null},
},
VerifyAccount: {
screen: VerifyAccount,
navigationOptions: {title: 'CategoryPerference', header: null},
},
});
export default AuthStack;
And OtherStack.tsx is similar to AuthStack.tsk with other screens. I keep getting this error. I think this is an issue with the navigation. I've updated react-navigation, react-navigation-stack but that doesn't seem to help.
I want to put the buttons under the header that I have made with the stack, but I can not think of how I leave a part of the code of how I have done it.
//stacks
import React from "react";
import { connect } from "react-redux";
import { createStackNavigator } from "react-navigation";
import ScreenAutoridades from "../../views/autoridades/ScreenAutoridades";
import DetallesAutoridades from "../../views/autoridades/autoridades/Components/DetallesAutoridades";
import AutoridadesList from "../../views/autoridades/autoridades/Components/AutoridadesList";
import ButtonMenu from "../components/ButtonMenu";
import ButtonHome from "../components/ButtonHome";
import { defaultNavigationOptions } from "../components/stylesNavigations";
let AutoridadesRedux = connect(state => ({
autoridades: state.autoridades
}))(ScreenAutoridades);
const AutoridadesStack = createStackNavigator(
{
AUTORIDADES: {
screen: AutoridadesRedux,
navigationOptions: ({ navigation }) => {
return {
headerLeft: <ButtonMenu navigation={navigation} />,
headerRight: <ButtonHome navigation={navigation} />
};
}
},
AutoridadesList: {
screen: AutoridadesList
},
DetalleAutoridades: {
screen: DetallesAutoridades
}
},
{
defaultNavigationOptions
}
);
export { AutoridadesStack };
//Drawer
const DrawerNavigator = createDrawerNavigator(
{
Diputados: { screen: DiputadosStack },
Bloques: { screen: BloquesStack },
Interbloques: { screen: InterBloquesStack },
Comisiones: { screen: ComisionesStack },
Autoridades: { screen: AutoridadesStack },
"Sesion En Vivo": { screen: SesionEnVivoStack },
"Diputados TV": { screen: DiputadosTVStack },
"Reglamentos HCDN": { screen: PDFReglamentosStack }
},
{
contentComponent: CustomDrawerContentComponent,
drawerWidth: width / 2,
contentOptions: {
activeTintColor: white,
activeBackgroundColor: Gris_Drawer,
inactiveTintColor: "rgb(105,105,104)",
itemsContainerStyle: {
textAlign: "center"
},
labelStyle: {
fontFamily: "RobotoCondensed-Regular",
fontWeight: "100",
fontSize: 17,
marginTop: 8,
marginLeft: 10
}
},
iconContainerStyle: {
opacity: 1
}
}
);
I just want to add the createMaterialTopTabNavigator below the header made with the createStackNavigator.
What I did was put a createMaterialTopTabNavigator but at the time of adding the stacks inside I stayed up the createMaterialTopTabNavigator and below I had the navigation of the stack
You can use a navigator for a screen in creating any navigator.
For example:
import {
createMaterialTopTabNavigator,
createStackNavigator
} from 'react-navigation'
import MyComponent from '../some-component-folder/'
import MyHomeComponent from '../some-component-folder/'
import MyNavigator from '../some-navigator-folder/'
const TabNavigator = createMaterialTopTabNavigator(
{
Tab1: { screen: MyComponent }
Tab2: { screen: MyNavigator }
}
)
const StackNavigator = createStackNavigator(
{
Screen1: { screen: MyHomeComponent }
Screen2: { screen: TabNavigator }
}
)
I am developing an application and using the listener onAuthStateChanged from Firebase in my AuthenticationLoadingScreen so I can redirect the user based on this state, however, it just opens a white page and doesn't open the home screen.
EDIT: Someone says that maybe the app.js is the problem so I added it here
import HomeScreen from '../screens/HomeScreen'
import AuthScreen from '../screens/AuthScreen'
// Implementation of HomeScreen, OtherScreen, SignInScreen, AuthLoadingScreen
// goes here.
const AppStack = createStackNavigator({ Home: HomeScreen});
const AuthStack = createStackNavigator({ Home: HomeScreen });
export default createAppContainer(createSwitchNavigator(
{
AuthLoading: AuthScreen,
App: AppStack,
Auth: AuthStack
},
{
initialRouteName: 'AuthLoading',
}
));
export default class AuthScreen extends React.Component {
constructor(props){
super(props);
}
componentDidMount = ()=>{
firebase.auth().onAuthStateChanged(user => {
this.props.navigation.navigate(user ? 'App' : 'Auth');
});
}
render() {
return (
<ImageBackground
source={require('../assets/images/AuthScreenBackground.png')}
style={styles.ImageBackground}/>
);
}
}
Here is the App.js code:
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import AppNavigation from './navigation/AppNavigation.js'
import * as firebase from 'firebase'
var config = {
};
firebase.initializeApp(config);
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<AppNavigation/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
Try this code:
componentWillMount() {
this.observeLogin = firebase.auth().onAuthStateChanged(user => {
if (user) {
this.props.navigation.navigate('App');
} else {
this.props.navigation.navigate('Auth');
}
});
}
componentWillUnmount() {
// Don't forget to unsubscribe when the component unmounts
this.observeLogin ();
}
I am trying out react navigation, but I seem to be having trouble with navigating to a nested DrawerNavigator route within my react native app.
After a successful login action, I would like to navigate to the Home screen but it doesn’t work
My setup looks like the following;
App.js
import React, { Component } from 'react';
import { View } from 'react-native';
import { StackNavigator, DrawerNavigator, addNavigationHelpers } from 'react-navigation';
import { Provider, connect } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import ReduxThunk from 'redux-thunk';
import reducers from './reducers';
import AppNavigator from './AppNavigator';
class App extends React.Component {
render() {
return (
<AppNavigator navigation={addNavigationHelpers({
dispatch: this.props.dispatch,
state: this.props.nav,
})} />
);
}
}
const mapStateToProps = (state) => ({
nav: state.nav
});
const AppWithNavigationState = connect(mapStateToProps)(App);
class Root extends Component {
render() {
const store = createStore(reducers, {}, applyMiddleware(ReduxThunk));
return (
<Provider store={ store }>
<View style={{ flex: 1 }}>
<AppWithNavigationState />
</View>
</Provider>
);
}
}
export default Root;
NavReducer.js
import { NavigationActions } from 'react-navigation';
import AppNavigator from '../AppNavigator';
const initialState = AppNavigator.router.getStateForAction(
NavigationActions.init()
// AppNavigator.router.getActionForPathAndParams('Main')
);
export default navReducer = (state = initialState, action) => {
const nextState = AppNavigator.router.getStateForAction(action, state);
// Simply return the original `state` if `nextState` is null or undefined.
return nextState || state;
};
AppNavigator.js
import { StackNavigator, DrawerNavigator } from 'react-navigation';
import LandingPage from './components/LandingPage';
import LoginScreen from "./components/LoginForm";
import RegistrationScreen from "./components/RegistrationForm";
import Homepage from "./components/Homepage";
const LoginStack = StackNavigator({
LandingPage: { screen: LandingPage },
Login: { screen: LoginScreen },
Registration: { screen: RegistrationScreen },
}, {
headerMode: 'none',
initialRouteName: 'LandingPage'
});
const DrawerNavigatorStack = DrawerNavigator({
Home: { screen: Homepage }
}, {
headerMode: 'none',
initialRouteName: 'Home'
});
const DrawerNavigation = StackNavigator({
DrawerStack: { screen: DrawerNavigatorStack }
}, {
headerMode: 'none',
initialRouteName: 'DrawerStack'
});
const AppNavigator = StackNavigator({
LoginStack: { screen: LoginStack },
Main: { screen: DrawerNavigation }
}, {
headerMode: 'none',
initialRouteName: 'LoginStack'
});
export default AppNavigator;
Login action
export const loginUser = ({ email, password }) => {
return (dispatch) => {
dispatch({ type: LOGIN_USER });
const data = {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: email,
password: password
})
};
const url = Globals.API_URL + 'accounts/login';
return fetch(url, data)
.then(response => {
const responseBody = JSON.parse(response._bodyText);
if (response.status === 200) {
dispatch({ type: LOGIN_USER_SUCCESS });
dispatch(NavigationActions.navigate({
routeName: ‘Home’, <=== supposed to navigate to the Home screen at this point
params: responseBody.data.access_token
}));
} else {
loginUserFail(dispatch, responseBody.message);
}
});
}
}
It successfully dispatches the LOGIN_USER_SUCCESS and the subsequent Navigation actions, but it doesn’t actually navigate to the Home screen
If I replace the ‘Home’ route with a route from the ‘LoginStack’ it will navigate to that screen with no problem. So for example, this would work
dispatch(NavigationActions.navigate({
routeName: ‘LandingPage’, <=== will successfully navigate back to the LandingPage
params: responseBody.data.access_token
}));
I’m obviously missing something, any ideas what that might be?
Thanks in advance
I've been working on my first React Native project. It is a Multiscreen App, and one of the screens requires some data, which I'm passing from the parent screen. But the issue is that when I receive the data in the child screen, and try to save the value in the screen's state, the app crashes. As soon as I remove the code that accesses the state, it does not crash. Here's the code:
renderRow(object) { //Calling the second screen when the user touches
const { navigate } = this.props.navigation;
return(
<TouchableOpacity onPress={() => navigate('ViewRecord', { key: object.key })}> //Sending the parameter
<Image
styleName="large-square"
source={{ uri: object.record.image }} >
<Text style={styles.designNumberHeading}>{object.record.designNumber}</Text>
</Image>
</TouchableOpacity>
);
}
Here is the code of the Child Screen:
'use-strict'
import React, { Component } from 'react';
import {
StyleSheet,
View,
KeyboardAvoidingView,
ScrollView,
TouchableHighlight,
Text,
FlatList,
} from 'react-native';
import {
Heading,
Title,
TextInput,
Button,
Image,
NavigationBar,
ListView,
TouchableOpacity,
Icon,
Lightbox,
Overlay,
} from '#shoutem/ui';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import NavBar from '../components/NavBar.js';
import { firebaseApp } from '../config/firebase.js';
export default class ViewRecord extends Component{
constructor(props) {
super(props);
this.state={
designNumber: '',
dates: [],
quantity: 0,
karigars: [],
colour:'',
amount: '',
description: '',
editMode: false,
};
this.updateStateAfterGettingData = this.updateStateAfterGettingData.bind(this);
}
getData() {
const { params } = this.props.navigation.state; //Accessing the parameters
console.log('Key: ', params.key);
let databaseRef = firebaseApp.database().ref(params.key);
databaseRef.once('value', (snap) => {
console.log('Inside Event Listener');
this.updateStateAfterGettingData(snap); //Setting the state. (The App crashes if this statement is executed)
});
}
updateStateAfterGettingData(snap) {
this.setState({
designNumber: snap.val().designNumber,
dates: snap.val().dates,
quantity: snap.val().quantity,
karigars: snap.val().karigars,
colour: snap.val().colour,
amount: snap.val().amount,
materials: snap.val().materials,
description: snap.val().description,
});
console.log(this.state);
}
render() {
const { goBack } = this.props.navigation;
this.getData();
if (!this.state.editMode) {
return(
<View style={styles.container}>
<NavBar title="View Record" hasHistory={true} goBack={() => goBack()}/>
</View>
);
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FFFFFF',
},
})
Here is the code of the StackNavigator:
import { StackNavigator } from 'react-navigation';
import CreateRecord from '../screens/CreateRecord.js';
import Records from '../screens/Records.js';
import ViewRecord from '../screens/ViewRecord.js';
export const Navigator = StackNavigator({
Records: { screen: Records },
CreateRecord: { screen: CreateRecord },
ViewRecord: { screen: ViewRecord },
},
{
headerMode: 'none',
navigationOptions: {
headerVisible: false,
}
});
Now, how can I manipulate the state of the ViewRecord.js class when accepting parameters?
PS: I am using Expo along with Create React Native App