Skip to main content
Version: 3.x

Common mistakes

This section attempts to outline issues that users frequently encounter when first getting accustomed to using React Navigation and serves as a reference in some cases for error messages.

Explicitly rendering more than one navigator​

Most apps should only ever render one navigator inside of a React component, and this is usually somewhere near the root component of your app. This is a little bit counter-intuitive at first but it's important for the architecture of React Navigation.

Here's what you might write in your code -- note that this example would be incorrect:

export default class App extends React.Component {
render() {
/* In the root component we are rendering the app navigator */
return <AppContainer />;
}
}

const AuthenticationNavigator = createStackNavigator({
SignIn: SignInScreen,
ForgotPassword: ForgotPasswordScreen,
});

const AuthenticationContainer = createAppContainer(AuthenticationNavigator);

class AuthenticationScreen extends React.Component {
render() {
/*
* In a screen inside of the navigator we are rendering another navigator
* You should avoid this! It will have its own navigation state and be unable
* To interact with any parent navigator, eg: it would not know the route "Home" exists
*/
return <AuthenticationContainer />;
}
}

const AppNavigator = createSwitchNavigator({
Auth: AuthenticationScreen, // This screen renders a navigator!
Home: HomeScreen,
});

const AppContainer = createAppContainer(AppNavigator);

The correct way to write this would be the following:

export default class App extends React.Component {
render() {
return <AppContainer />;
}
}

const AuthenticationNavigator = createStackNavigator({
SignIn: SignInScreen,
ForgotPassword: ForgotPasswordScreen,
});

const AppNavigator = createSwitchNavigator({
/*
* Rather than being rendered by a screen component, the
* AuthenticationNavigator is a screen component
*/
Auth: AuthenticationNavigator,
Home: HomeScreen,
});

const AppContainer = createAppContainer(AppNavigator);

Alternatively, the following would also work because it exposes the router static on AuthenticationScreen and threads through the navigation prop:

export default class App extends React.Component {
render() {
/* In the root component we are rendering the app navigator */
return <AppContainer />;
}
}

const AuthenticationNavigator = createStackNavigator({
SignIn: SignInScreen,
ForgotPassword: ForgotPasswordScreen,
});

class AuthenticationScreen extends React.Component {
static router = AuthenticationNavigator.router;

render() {
return <AuthenticationNavigator navigation={this.props.navigation} />;
}
}

const AppNavigator = createSwitchNavigator({
Auth: AuthenticationScreen, // This screen renders a navigator!
Home: HomeScreen,
});

const AppContainer = createAppContainer(AppNavigator);

Assigning navigationOptions to the wrong component​

In previous version of React Navigation, the library used to dig through your component tree to find navigationOptions. This is no longer the case, and only navigationOptions on screen components of a particular navigator will apply to that navigator. You can read more about this in the Navigation options resolution guide.

Wrapping AppContainer in a View without flex​

If you wrap the AppContainer in a View, make sure the View is using flex.

import React from 'react';
import { Text, View } from 'react-native';
import { createBottomTabNavigator, createAppContainer } from 'react-navigation';
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
</View>
);
}
}
class SettingsScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
</View>
);
}
}
const TabNavigator = createBottomTabNavigator({
Home: HomeScreen,
Settings: SettingsScreen,
});
const AppContainer = createAppContainer(TabNavigator);
// without the style you will see a blank screen
export default () => (
<View style={{ flex: 1 }}>
<AppContainer />
</View>
);