By Hendry Lim

2017-03-18 16:09:44 8 Comments

I am trying to use react-navigation to create a initial LOGIN screen which has no tabbar and header, and once the user has been successfully authenticated will navigate to another screen called LISTRECORD which has a tabbar, header and no back button option. Anyone has experience in this and can share?

In summary, what i m trying to achieve with react-navigation is described below...

Screen 1: Login Screen (No Header & Tabbar)
Screen 2: LISTRECORD (Header, Tabbar and No Back Button)
The tabbar contains other tabs too for navigation to Screen 3, Screen 4...


@Francois Nadeau 2018-12-14 14:43:14

I needed this, but none of the other solutions worked for me. So here is my solution for a Login with a drawer (the latter accessible only after proper authentication, and each of the screens inside have there own navigation stack). My code has a DrawerNavigator, but the same could be used for a TabNavigator (createBottomTabNavigator).

wrapScreen = stackNavigator =>
  createStackNavigator(stackNavigator, {
    defaultNavigationOptions: ({ navigation }) => ({
      headerStyle: { backgroundColor: "white" },
      headerLeft: MenuButton(navigation)

const DrawerStack = createDrawerNavigator(
    // Menu Screens
    firstSection: wrapScreen({ FirstScreen: FirstScreen }),
    secondSection: wrapScreen({
      SecondHomeScreen: SecondHomeScreen,
      SecondOptionScreen: SecondOptionScreen
    settingSection: wrapScreen({ SettingScreen: SettingScreen }),
    aboutSection: wrapScreen({ AboutScreen: AboutScreen })
    initialRouteName: "firstSection",
    gesturesEnabled: false,
    drawerPosition: "left",
    contentComponent: DrawerContainer

const PrimaryNav = createSwitchNavigator(
    loginStack: LoginScreen,
    appStack: DrawerStack
  { initialRouteName: "loginStack" }

export default createAppContainer(PrimaryNav);

I hope it can help others.

@Hendry Lim 2018-12-14 23:43:50

Thanks Francois. Since i started this post in beginning 2017, react navigation api has been changing hence some code suggestions might have been made irrelevant depending on the rn version installed as your dependency. I have a repository (link below) which uses react navigation, authentication with graphql. It also features many other modules like pagination and image uploading. It is still a work in progress for other modules. Happy coding. Link:

@cutemachine 2018-05-22 19:58:27

There is now good documentation on the react-navigation site about the authentication flow.

@Manjeet Singh 2017-03-28 09:02:40

this is how I achived this functionality.

File 0)

'use strict'

import React, { Component } from 'react';
import {
} from 'react-native';

import Root from 'src/containers/Root'

AppRegistry.registerComponent('Riduk', () => Root);

File 1)my Root.js

class Root extends Component {
    constructor(props) {
      this.state = {
        store: configureStore(() => this.setState({isLoading: false})),

  componentDidMount() {
    //you can do check with authentication with fb, gmail and other right here
   /* firebase.auth().onAuthStateChanged((user) => {
      if (user) {
        api.resetRouteStack(dispatch, "UserProfile");
        console.log("authenticated", user);
      } else {
        api.resetRouteStack(dispatch, "Landing");
        console.log("authenticated", false);


  render() {
    if (this.state.isLoading) {  //checking if the app fully loaded or not, splash screen can be rendered here
        return null;
      return (

        <Provider store={}>

module.exports = Root;


import AppWithNavigationState,{AppBeforeLogin} from './AppNavigator';

class App extends Component{

        let {authenticated} = this.props;
            return <AppWithNavigationState/>;
        return <AppBeforeLogin/>


export default connect(state =>({authenticated: state.user.authenticated}))(App);


'use strict';

import React, {Component} from 'react';
import { View, BackAndroid, StatusBar,} from 'react-native';
import {
} from 'react-navigation';
import { connect} from 'react-redux';

import LandingScreen from 'src/screens/landingScreen';
import Login from 'src/screens/login'
import SignUp from 'src/screens/signUp'
import ForgotPassword from 'src/screens/forgotPassword'
import UserProfile from 'src/screens/userProfile'
import Drawer from 'src/screens/drawer'

const routesConfig = {
  Login: { screen: Login },
  SignUp: { screen: SignUp },
  ForgotPassword: { screen: ForgotPassword },

export const AppNavigator = StackNavigator(routesConfig, {initialRouteName:'UserProfile'}); //navigator that will be used after login

export const AppBeforeLogin = StackNavigator(routesConfig); //naviagtor for before login

class AppWithNavigationState extends Component{
  constructor(props) {
    this.handleBackButton = this.handleBackButton.bind(this);

  componentDidMount() {
    BackAndroid.addEventListener('hardwareBackPress', this.handleBackButton);

  componentWillUnmount() {
    BackAndroid.removeEventListener('hardwareBackPress', this.handleBackButton);

  //added to handle back button functionality on android
  handleBackButton() {
    const {nav, dispatch} = this.props;

    if (nav && nav.routes && nav.routes.length > 1) {
      return true;
    return false;

  render() {
    let {dispatch, nav} = this.props;

    return (
          <View style={styles.container}>
            {(api.isAndroid()) &&
            <AppNavigator navigation={addNavigationHelpers({ dispatch, state: nav })}/>
export default connect(state =>({nav: state.nav}))(AppWithNavigationState);
//module.exports = AppWithNavigationState;

@Hendry Lim 2017-03-28 09:57:33

Thanks a lot! I ll look at it. Appreciate

@Hendry Lim 2017-03-29 00:01:44

Hi Manjeet, i ll need to use Redux to make your code work? Thks

@Manjeet Singh 2017-03-29 07:09:03

Yes it is with redux only, you can do similar thing without redux and using less code

@Hendry Lim 2017-03-29 07:56:53

Thanks Manjeet! ๐Ÿ˜Š I am trying to wrap my head around redux. Ll give it a shot. Thanks

@AlxVallejo 2017-05-10 18:12:36

I dont see your need for App.js. Couldn't you just put that render in Root render?

@Manjeet Singh 2017-05-11 09:13:10

@AlxVallejo I agree to that, but at that time I thought it may grow in future.

@Khushboo Gupta 2018-06-18 11:23:47

If you want no back button from your LIST page to LOGIN page, you can do this:

    static navigationOptions = {
        title: 'YOUR TITLE',
        headerLeft : null,

@Francois Nadeau 2018-12-14 14:33:41

That won't work on Android, since the users can still tap on the back button on the device, and it will take them back to the login page.

@bennygenel 2018-04-10 08:37:27

react-navigation now has a SwitchNavigator which helps desired behavior and switching between navigators. Currently there is not much documentation about it but there is a really good example snack created by the library which shows a simple authentication flow implementation. You can check it here.

SwitchNavigator reference

SwitchNavigator(RouteConfigs, SwitchNavigatorConfig)

Example from docs

const AppStack = StackNavigator({ Home: HomeScreen, Other: OtherScreen });
const AuthStack = StackNavigator({ SignIn: SignInScreen });

export default SwitchNavigator(
    AuthLoading: AuthLoadingScreen,
    App: AppStack,
    Auth: AuthStack,
    initialRouteName: 'AuthLoading',

@ScreamZ 2018-02-21 10:06:33

I know that I'm old here, but this article saved my ass, I'm in hell with the navigation and now I'm feeling more confortable.

That guy is explaining the internal API that will allows you to build your navigation as exactly as you imagine, using a main stack navigator also.

It goes deep with an authentication example

Please clap this guy :-)

@geisterfurz007 2018-02-21 10:07:22

A link to a solution is welcome, but please ensure your answer is useful without it: add context around the link so your fellow users will have some idea what it is and why itโ€™s there, then quote the most relevant part of the page you're linking to in case the target page is unavailable. Answers that are little more than a link may be deleted.

@ScreamZ 2018-02-21 10:11:07

I improved the answer. Thanks. So please, reconsider your -1 on the probably top answer of the page. I know that manners are important, but content is also important. And what you done didn't helped the community here. I made the effort to explain what it is

@geisterfurz007 2018-02-21 10:24:30

I cannot undo my vote because I never cast one :) And please copy what is relevant from that link into your answer. If the link goes down your answer will basically become invalid. It also requires others to open another page which can possibly be blocked by a network etc making it useless.

@agm1984 2017-10-13 08:37:52

Oct 2017 I found this ridiculously confusing, so here is my solution starting from the top down:

I recommend starting a new project and literally just paste all this in and study it after. I commented the code big-time, so if you are stuck on any specific area, maybe the context can help you get back on track.

This post shows how to:

  1. completely setup React Native to run react-navigation
  2. Properly integrate with Redux
  3. Handle Android Back Button
  4. Nest Stack Navigators
  5. Navigate from child to parent navigators
  6. Reset the Navigation Stack
  7. Reset the Navigation Stack while navigating from child to parent (nested)


import { AppRegistry } from 'react-native'
import App from './src/App'

AppRegistry.registerComponent('yourappname', () => App)

src/App.js (this is the most important file because it brings all the shreds together)

import React, { Component } from 'react'
// this will be used to make your Android hardware Back Button work
import { Platform, BackHandler } from 'react-native'
import { Provider, connect } from 'react-redux'
import { addNavigationHelpers } from 'react-navigation'
// this is your root-most navigation stack that can nest
// as many stacks as you want inside it
import { NavigationStack } from './navigation/nav_reducer'
// this is a plain ol' store
// same as const store = createStore(combinedReducers)
import store from './store'

// this creates a component, and uses magic to bring the navigation stack
// into all your components, and connects it to Redux
// don't mess with this or you won't get
// this.props.navigation.navigate('somewhere') everywhere you want it
// pro tip: that's what addNavigationHelpers() does
// the second half of the critical logic is coming up next in the nav_reducers.js file
class App extends Component {
    // when the app is mounted, fire up an event listener for Back Events
    // if the event listener returns false, Back will not occur (note that)
    // after some testing, this seems to be the best way to make
    // back always work and also never close the app
    componentWillMount() {
        if (Platform.OS !== 'android') return
        BackHandler.addEventListener('hardwareBackPress', () => {
            const { dispatch } = this.props
            dispatch({ type: 'Navigation/BACK' })
            return true

    // when the app is closed, remove the event listener
    componentWillUnmount() {
        if (Platform.OS === 'android') BackHandler.removeEventListener('hardwareBackPress')

    render() {
        // slap the navigation helpers on (critical step)
        const { dispatch, nav } = this.props
        const navigation = addNavigationHelpers({
            state: nav
        return <NavigationStack navigation={navigation} />

// nothing crazy here, just mapping Redux state to props for <App />
// then we create your root-level component ready to get all decorated up
const mapStateToProps = ({ nav }) => ({ nav })
const RootNavigationStack = connect(mapStateToProps)(App)

const Root = () => (
    <Provider store={store}>
        <RootNavigationStack />

export default Root


// NavigationActions is super critical
import { NavigationActions, StackNavigator } from 'react-navigation'
// these are literally whatever you want, standard components
// but, they are sitting in the root of the stack
import Splash from '../components/Auth/Splash'
import SignUp from '../components/Auth/SignupForm'
import SignIn from '../components/Auth/LoginForm'
import ForgottenPassword from '../components/Auth/ForgottenPassword'
// this is an example of a nested view, you might see after logging in
import Dashboard from '../components/Dashboard' // index.js file

const WeLoggedIn = StackNavigator({
    LandingPad: {             // if you don't specify an initial route,
        screen: Dashboard     // the first-declared one loads first
}, {
    headerMode: 'none'
    initialRouteName: LandingPad // if you had 5 components in this stack,
})                               // this one would load when you do
                                 // this.props.navigation.navigate('WeLoggedIn')

// notice we are exporting this one. this turns into <RootNavigationStack />
// in your src/App.js file.
export const NavigationStack = StackNavigator({
    Splash: {
        screen: Splash
    Signup: {
        screen: SignUp
    Login: {
        screen: SignIn
    ForgottenPassword: {
        screen: ForgottenPassword
    WeLoggedIn: {
        screen: WeLoggedIn  // Notice how the screen is a StackNavigator
    }                       // now you understand how it works!
}, {
    headerMode: 'none'

// this is super critical for everything playing nice with Redux
// did you read the React-Navigation docs and recall when it said
// most people don't hook it up correctly? well, yours is now correct.
// this is translating your state properly into Redux on initialization    
const INITIAL_STATE = NavigationStack.router.getStateForAction(NavigationActions.init())

// this is pretty much a standard reducer, but it looks fancy
// all it cares about is "did the navigation stack change?"    
// if yes => update the stack
// if no => pass current stack through
export default (state = INITIAL_STATE, action) => {
    const nextState = NavigationStack.router.getStateForAction(action, state)

    return nextState || state


// remember when I said this is just a standard store
// this one is a little more advanced to show you
import { createStore, compose, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import { persistStore, autoRehydrate } from 'redux-persist'
import { AsyncStorage } from 'react-native'
// this pulls in your combinedReducers
// nav_reducer is one of them
import reducers from '../reducers'

const store = createStore(

persistStore(store, { storage: AsyncStorage, whitelist: [] })

// this exports it for App.js    
export default store


// here is my reducers file. i don't want any confusion
import { combineReducers } from 'redux'
// this is a standard reducer, same as you've been using since kindergarten
// with action types like LOGIN_SUCCESS, LOGIN_FAIL
import loginReducer from './components/Auth/login_reducer'
import navReducer from './navigation/nav_reducer'

export default combineReducers({
    auth: loginReducer,
    nav: navReducer


I will show you a sample here. This isn't mine, I just typed it out for you in this rickety StackOverflow editor. Please give me thumbs up if you appreciate it :)

import React, { Component } from 'react'
import { View, Text, TouchableOpacity } from 'react-native

// notice how this.props.navigation just works, no mapStateToProps
// some wizards made this, not me
class SignUp extends Component {
    render() {
        return (
                <TouchableOpacity onPress={() => this.props.navigation.navigate('Login')}>
                    <Text>Go to Login View</Text>

export default SignUp


I'll show you a dumb style one also, with the super dope back button

import React from 'react'
import { View, Text, TouchableOpacity } from 'react-native

// notice how we pass navigation in
const SignIn = ({ navigation }) => {
    return (
            <Text>Log in</Text>
            <TouchableOpacity onPress={() => navigation.goBack(null)}>
                <Text>Go back to Sign up View</Text>

export default SignIn


Here is a splash screen you can play around with. I am using it like a higher-order component:

import React, { Component } from 'react'
import { StyleSheet, View, Image, Text } from 'react-native'
// this is a library you REALLY should be using
import * as Animatable from 'react-native-animatable' 
import { connect } from 'react-redux'
import { initializeApp } from './login_actions'

class Splash extends Component {
    constructor(props) {
        this.state = {}

    componentWillMount() {
        setTimeout(() => this.props.initializeApp(), 2000)

    componentWillReceiveProps(nextProps) {
        // if (!nextProps.authenticated) this.props.navigation.navigate('Login')
        if (nextProps.authenticated) this.props.navigation.navigate('WeLoggedIn')

    render() {
        const { container, image, text } = styles
        return (
            <View style={container}>

                    <Text>{(this.props.authenticated) ? 'LOGGED IN' : 'NOT LOGGED IN'}</Text>

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F0F0F0'
    image: {
        height: 110,
        resizeMode: 'contain'
    text: {
        marginTop: 50,
        fontSize: 15,
        color: '#1A1A1A'

// my LOGIN_SUCCESS action creator flips state.auth.isAuthenticated to true    
// so this splash screen just watches it
const mapStateToProps = ({ auth }) => {
    return {
        authenticated: auth.isAuthenticated

export default connect(mapStateToProps, { initializeApp })(Splash)


I'm just going to show you initializeApp() so you get some ideas:

import {
} from './login_types'

// this isn't done, no try/catch and LOGIN_FAIL isn't hooked up
// but you get the idea
// if a valid JWT is detected, they will be navigated to WeLoggedIn
export const initializeApp = () => {
    return async (dispatch) => {
        dispatch({ type: INITIALIZE_APP })

        const user = await AsyncStorage.getItem('token')
            .catch((error) => dispatch({ type: LOGIN_FAIL, payload: error }))

        if (!user) return dispatch({ type: LOGIN_FAIL, payload: 'No Token' })

        return dispatch({
            type: LOGIN_SUCCESS,
            payload: user
        // navigation.navigate('WeLoggedIn')
        // pass navigation into this function if you want

In other use cases, you may prefer the higher-order component. They work exactly the same as React for web. Stephen Grider's tutorials on Udemy are the best, period.


import React, { Component } from 'react'
import { connect } from 'react-redux'

export default function (ComposedComponent) {
    class Authentication extends Component {

        componentWillMount() {
            if (!this.props.authenticated) this.props.navigation.navigate('Login')

        componentWillUpdate(nextProps) {
            if (!nextProps.authenticated) this.props.navigation.navigate('Login')

        render() {
            return (
                <ComposedComponent {...this.props} />

    const mapStateToProps = ({ auth }) => {
        return {
            authenticated: auth.isAuthenticated

    return connect(mapStateToProps)(Authentication)

You use it just like this:

import requireAuth from '../HOC/require_auth'

class RestrictedArea extends Component {
    // ... normal view component

//map state to props

export default connect(mapStateToProps, actions)(requireAuth(RestrictedArea))

There, that is everything I wish someone told and showed me.

TLDR The App.js, and nav_reducer.js files are absolutely the most important to get right. The rest is old familiar. My examples should accelerate you into a savage productivity machine.

[Edit] Here is my logout action creator. You will find it very useful if you wish to wipe off your navigation stack so the user cannot press Android Hardware Back Button and go back to a screen that requires authentication:

export const onLogout = (navigation) => {
    return async (dispatch) => {
        try {
            await AsyncStorage.removeItem('token')

                type: 'Navigation/RESET',
                index: 0,
                actions: [{ type: 'Navigate', routeName: 'Login' }]

            return dispatch({ type: LOGOUT })
        } catch (errors) {
            // pass the user through with no error
            // this restores INITIAL_STATE (see login_reducer.js)
            return dispatch({ type: LOGOUT })

// login_reducer.js
    case LOGOUT: {
        return {
            isAuthenticated: false,

[bonus edit] How do I navigate from a child Stack Navigator to a parent Stack Navigator?

If you want to navigate from one of your child Stack Navigators and reset the stack, do this:

  1. Be inside a component adding code, where you have this.props.navigation available
  2. Make a component like <Something />
  3. Pass navigation into it, like this: <Something navigation={this.props.navigation} />
  4. Go into the code for that component
  5. Notice how you have this.props.navigation available inside this child component
  6. Now you're done, just call this.props.navigation.navigate('OtherStackScreen') and you should watch React Native magically go there without problem

But, I want to RESET the whole stack while navigating to a parent stack.

  1. Call an action creator or something like this (starting off from step 6): this.props.handleSubmit(data, this.props.navigation)
  2. Go into the action creator and observe this code that could be there:


// we need this to properly go from child to parent navigator while resetting
// if you do the normal reset method from a child navigator:
    type: 'Navigation/RESET',
    index: 0,
    actions: [{ type: 'Navigate', routeName: 'SomeRootScreen' }]

// you will see an error about big red error message and
// screen must be in your current stack 
// don't worry, I got your back. do this
// (remember, this is in the context of an action creator):
import { NavigationActions } from 'react-navigation'

// notice how we passed in this.props.navigation from the component,
// so we can just call it like Dan Abramov mixed with Gandolf
export const handleSubmit = (token, navigation) => async (dispatch) => {
    try {
        // lets do some operation with the token
        await AsyncStorage.setItem('[email protected]', token)
        // let's dispatch some action that doesn't itself cause navigation
        // if you get into trouble, investigate shouldComponentUpdate()
        // and make it return false if it detects this action at this moment
        dispatch({ type: SOMETHING_COMPLETE })

        // heres where it gets 100% crazy and exhilarating
        return navigation.dispatch(NavigationActions.reset({
            // this says put it on index 0, aka top of stack
            index: 0,
            // this key: null is 9001% critical, this is what
            // actually wipes the stack
            key: null,
            // this navigates you to some screen that is in the Root Navigation Stack
            actions: [NavigationActions.navigate({ routeName: 'SomeRootScreen' })]
    } catch (error) {
        dispatch({ type: SOMETHING_COMPLETE })
        // User should login manually if token fails to save
        return navigation.dispatch(NavigationActions.reset({
            index: 0,
            key: null,
            actions: [NavigationActions.navigate({ routeName: 'Login' })]

I am using this code inside an enterprise-grade React Native app, and it works beautifully.

react-navigation is like functional programming. It is designed to be handled in small "pure navigation" fragments that compose well together. If you employ the strategy described above, you will find yourself creating re-useable navigation logic that you can just paste around as needed.

@agm1984 2017-10-23 07:44:45

You may encounter some anomalies with the Splash screen and logging in/out, but you will solve them easily. I've changed my flow a couple times since this post, and the changes are trivial once you understand what I've posted here. My flow changed due to hooking up Apollo Client.

@Jim Wrubel 2017-11-21 13:05:17

It's pretty rare that an answer on SO contains an entire high-quality application framework. - thank you a billion times for this. I think the react-navigation library as well as the entire RN community would benefit from this being widely shared. If it's not already would you be willing to put it into a Medium post or other format? I'm happy to help (or even write it up myself but I don't want to take credit for your fantastic work here).

@agm1984 2017-11-22 08:58:45

Thanks, and I agree. I made it because figuring it out was literally double as hard as anything I had encountered before it, learning React Web and Native. I don't want anyone to experience that ever again. I planned on putting it into a Medium post since it won't get proper visibility here. I will start putting that together today and cite you in it as the impetus.

@Manjeet Singh 2017-11-29 12:34:31

@agm1984, Thanks for great answer, it is pretty helpful.Were you able to test reset functionality for nested stacknavigator within tabnavigator. if we are within a stacknavigator that is child of tabNavigator (let say tab1 out of tab2), it seems to not work when I am trying to move to tab2 from a screen within tab1

@Hiroki 2017-12-14 06:03:25

Thank you for suggesting NavigationActions.init(). I don't understand why the official doc doesn't show an example of it.

@raarts 2018-01-28 10:22:29

Note that redux-persist is now at version 5, breaking this example. See:…

@izikandrw 2018-03-08 00:10:06

Because my initial state isAuthenticated is false, when my initializeApp function shows I'm not logged in (false), the componentWillReceiveProps method doesn't get triggered and so I'm stuck on the splash page. How to get to login screen?

@agm1984 2018-03-08 23:21:52

The initializeApp function is an action creator that very specifically finds the token or does not. Your case is that it does not, so your mission is to find a way to tell the Splash View that the result of initializeApp was "not logged in". In my example, the Splash View is listening to state.auth.isAuthenticated which starts as null which isnt true or false. This lets the app know that there is no definitive answer yet. The component listens for changes to that state property. initializeApp could set it to false and the component will know. Look at the commented-out line.

@Jalal El-Shaer 2018-04-13 12:17:05

Great answer. Any chance we can see this wrapped in a github sample. It would be an excellent resources for starters.

@F.E Noel Nfebe 2017-05-28 01:56:00

Its good that you are using react-navigation which has a good support for most of the features your app requires. Heres my advice

1) On Authentication

React-native has this nice feature state variables which when changed views are re-rendered. You can use state variables to understand the "state" (authenticated/visitor) of the users of your app.

Here is a simple implementation where a user logs in by pressing a login button

Entry page where user logs in

import React from 'react';

import Home from './layouts/users/home/Home';
import Login from './layouts/public/login/Login';

class App extends React.Component {

    state = {
        isLoggedIn: false

    componentDidMount() {
        //Do something here like hide splash screen

        if (this.state.isLoggedIn)
         return <Home

         return <Login
         onLoginPress={() => this.setState({isLoggedIn: true})}


export default App;

2) Login with header

Login View

import React from 'react';
//Non react-native import
import { TabNavigator } from 'react-navigation'
import Icon from 'react-native-vector-icons/MaterialIcons'
import LoginStyles from './Style'
//Do all imports found in react-native here
import {
} from 'react-native';

class Login extends React.Component {

         return (
         Login area

                onPress={this.props.onLoginPress}   >

                <Text style={LoginStyles.button}>



export default Login;

Remember to remove the style attributes in the login screen and add yours including import, I am leaving them there as it can help you have and idea how you can arrange you react project

However it still works without the styles so you can take them off, clicking the login button will take you to the Home screen, since the state changed and the view has to be re-rendered according to new state

The login screen is without a header as you required

Home screen with tabs

3) Tabs with header The general method to achieve this functionality it to add a TabNavigator in a StackNavigator.

       import React from 'react';
    import {
    } from 'react-navigation'
    import Icon from 'react-native-vector-icons/MaterialIcons'

    //Do all imports found in react-native here
    import {
    } from 'react-native';

class PicturesTab extends React.Component {
  static navigationOptions = {
    tabBarLabel: 'Pictures',
    // Note: By default the icon is only shown on iOS. Search the showIcon option below.
    tabBarIcon: ({ tintColor }) =>  (<Icon size={30} color={tintColor} name="photo" />),

  render() { return <Text>Pictures</Text> }

class VideosTab extends React.Component {
  static navigationOptions = {
    tabBarLabel: 'Videos',
    tabBarIcon: ({ tintColor }) =>  (<Icon size={30} color={tintColor} name="videocam" />),

  render() { return <Text>Videos</Text> }


    const HomeTabs = TabNavigator({
      Pictures: {
        screen: PicturesTab,
      Videos: {
        screen: VideosTab,
    }, {
        tabBarComponent: TabBarBottom,
        tabBarPosition: 'bottom',
        tabBarOptions: {
        //Thick teal #094545
        activeTintColor: '#094545',
        showLabel: false,
        activeBackgroundColor: '#094545',
        inactiveTintColor: '#bbb',
        activeTintColor: '#fff',


    const HomeScreen = StackNavigator({
      HomeTabs : { screen: HomeTabs,
        navigationOptions: ({ navigation }) => ({
        // title :'title',
        // headerRight:'put some component here',
        // headerLeft:'put some component here',
         headerStyle: {
           backgroundColor: '#094545'


    export default HomeScreen;

Disclaimer : Code may return errors as some files may be missing or some typos may be present you should check for details carefully and change where neccesary if you have to copy this code. Any problems can be pasted as comments. Hope this helps someone.

You may also remove the icons in the tab configurations or install the react-native-vector icons which makes tabs great!

@zechdc 2017-05-26 22:31:13

This is my solution based on @parker recommendation:

  1. Create a top level navigator and it should be a stack navigator that renders a login screen.
  2. Another screen within this top level navigator should be your app's Main-Navigator.
  3. When your login state is satisfied, you reset the main stack to just the Main-Navigator.

This code does the bare minimum to accomplish the above.

Create a new react-native project, then copy the code below into index.ios.js and/or to see it working.

import React, { Component } from 'react';
import {
} from 'react-native';
import { StackNavigator, NavigationActions } from 'react-navigation';

const resetAction = NavigationActions.reset({
  index: 0,
  actions: [
    NavigationActions.navigate({ routeName: 'Main' })

class LoginScreen extends Component {
  login() {

  render() {
    return <Button title='Login' onPress={() => {this.login()}} />;

class FeedScreen extends Component {
  render() {
    return <Text>This is my main app screen after login</Text>;

//Create the navigation
const MainNav = StackNavigator({
    Feed: { screen: FeedScreen },

const TopLevelNav = StackNavigator({
  Login: { screen: LoginScreen },
  Main: { screen: MainNav },
}, {
  headerMode: 'none',

AppRegistry.registerComponent('ReactNav2', () => TopLevelNav);

@Thomas 2017-07-10 21:22:57

How would you handle it if you want the login to persist after they click the button? Would you check to see if they've logged in inside the login file? Or would you make another screen called index, in which you would check if they've already logged in, and navigate them to the correct screen based off that?

@dchhetri 2017-10-16 04:43:25

Thanks for the snippet. Also how would you handle the case when user has already logged in. In that scenario there is no need to goto Login screen and we can just goto the main.

@Zennichimaro 2017-10-23 03:27:56

would you please explain your resetAction? is index:0 referring to TopLevelNav and action then referring to its Main route? sorry, new to react here

@Alan J. 2017-11-06 01:17:25

This works perfectly for my use case. Thank you! Follow up question though, did you ever implement a logout function? Can not figure out a similar method to logout and reset navigation to app default and go back to Login screen.

@sean 2017-11-10 23:15:59

For Logout, I think you could set a page to navigate back to the original navigation method, and reset the stack in the same way.

@JBaczuk 2019-05-09 17:55:18

For the resetAction I think NavigationsAction.reset should actually be StackActions.reset

@parker 2017-03-31 12:33:45

Although what Manjeet suggests will work, it is not a good navigational structure.

What you should do is take a step back and handle everything on another level.

Top level navigator should be a stack navigator that renders a login screen. Another screen within this top-most navigator should be your app's Main-Navigator. When your login state is satisfied, you reset the main stack to just the Main-Navigator.

The reason for this structure is:

A- What if you need to add on-boarding information before the Login the future?

B- What if you need to navigate outside of the Main-Navigation environment (eg: your main nav is tabs and you want a non-tab view)?

If your top-most navigator is a Stack-Navigator that presents Login screens and other Navigators, then your app's navigation structure can properly scale.

I do not believe the conditional rendering of a login screen or stack navigator, as suggested above, is a good me...I've gone down that road.

@Hendry Lim 2017-03-31 14:11:23

Thanks for your kind sharing Parker! :)

@Manjeet Singh 2017-05-05 18:45:14

actually I tried this structure in the start but due to some reason when I reload the app login screen comes for few seconds before moving to main dashboard

@parker 2017-06-02 19:38:30

Yes...this will happen while login information is retrieved form storage. That is why you implement a Splash Screen that gets dismissed once the proper information is read from storage (either successfully or on error, don't get caught with un-dismissible Splash Screen)

@Manjeet Singh 2017-06-08 07:24:00

ohhh I agree but I used native solution for splashscren

@Puneet Mahendra 2017-07-19 17:20:59

Can you please provide a code which explains "reset the main stack to just the Main-Navigator."?

@Alexis 2017-12-12 16:42:53

You should have a look at the navigation actions :

@kas 2018-03-27 13:49:04

@lucius degeer 2018-07-22 22:35:21

The Reset is explained here:

@luschn 2017-03-27 20:17:02

Make tabbar and header separate components and only include them in other components. About disabling "BACK", there is a section about "blocking navigation actions" in the docs:

You should be able to use that for screen 2.

@Manjeet Singh 2017-03-27 20:39:45

I am just curious to know what will happen if we refresh the app

@luschn 2017-03-27 20:47:34

you mean, if it goes back to the login screen? you could just check if the user is logged in already on the login screen (you have to do that somewhere anyway) and then forward him to screen 2 before showing the login screen for real. just a quick idea.

@Manjeet Singh 2017-03-28 08:00:35

yeah achieved this, created 2 navigation components, 1 for before login other for after login

@luschn 2017-03-28 08:05:59

can you create an answer with the relevant code? would be interesting for (and others) too :)

@Hendry Lim 2017-03-28 09:58:19

Thanks all. Appreciate your advice

Related Questions

Sponsored Content

12 Answered Questions

[SOLVED] Disable back button in react navigation

1 Answered Questions

[SOLVED] React Navigation navigate away from TabNavigator

1 Answered Questions

[SOLVED] Drawer navigation with top tabs after login

0 Answered Questions

Hide a screen in MaterialBottomTabNavigator (React Navigation)

1 Answered Questions

[SOLVED] React-Navigation: Navigation in nested navigators

1 Answered Questions

1 Answered Questions

2 Answered Questions

0 Answered Questions

Sponsored Content