Skip to content

Instantly share code, notes, and snippets.

@dereknahman
Created August 26, 2020 20:22
Show Gist options
  • Save dereknahman/bc618d8a614a116439faa0580b57df1a to your computer and use it in GitHub Desktop.
Save dereknahman/bc618d8a614a116439faa0580b57df1a to your computer and use it in GitHub Desktop.
navigation
import 'react-native-gesture-handler';
import React from 'react';
import SplashScreen from 'react-native-splash-screen';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createStackNavigator } from '@react-navigation/stack';
import HomeScreen from '../screens/HomeScreen';
import WelcomeScreen from '../screens/WelcomeScreen';
import AppMenuScreen from '../screens/AppMenuScreen';
import HowToUseThisAppScreen from '../screens/HowToUseThisAppScreen';
import ChooseYourLanguageScreen from '../screens/ChooseYourLanguageScreen';
// This is the tab navigator for the bottom tabs containing the Home and More stack navigators
const AppTabs = createBottomTabNavigator();
const AppTabsScreen = () => {
return (
<AppTabs.Navigator
AppTabsBarOptions={{
labelStyle: {
fontSize: 15,
fontWeight: '600',
marginBottom: 8,
},
}}>
<AppTabs.Screen name="Home" component={HomeScreen} />
<AppTabs.Screen name="App Menu" component={AppMenuScreen} />
</AppTabs.Navigator>
);
};
// This is the root stack navigator.
// It is currently the main skeleton of the navigation logic
const RootStack = createStackNavigator();
const RootStackScreen = () => {
React.useEffect(() => {
SplashScreen.hide();
}, []);
const [hasCompletedIntro, setHasCompletedIntro] = React.useState(false);
const [hasSelectedLanguage, setHasSelectedLanguage] = React.useState(true);
return (
<RootStack.Navigator>
{hasSelectedLanguage ? (
<RootStack.Screen name="Home" component={AppTabsScreen} />
) : (
<>
{!hasCompletedIntro ? (
<>
<RootStack.Screen
name="Choose Your Language"
component={ChooseYourLanguageScreen}
/>
<RootStack.Screen name="Welcome" component={WelcomeScreen} />
<RootStack.Screen
name="HowToUseThisApp"
component={HowToUseThisAppScreen}
/>
<RootStack.Screen name="Home" component={AppTabsScreen} />
</>
) : (
<>
<RootStack.Screen name="Home" component={AppTabsScreen} />
</>
)}
</>
)}
</RootStack.Navigator>
);
};
export default () => {
return (
<NavigationContainer>
<RootStackScreen />
</NavigationContainer>
);
};
@dereknahman
Copy link
Author

Right. So!

I tried out the code you sent (thank you). I am still struggling quite a lot, and am not sure if I can keep nesting ternaries because React Navigation v5 gets VERY upset when you use the same component more than one in the return statement.

This is what I'm trying to do:

  • If the user hasSelectedLanguage and hasCompletedIntro, they go straight to AppTabsScreen.
  • If the user hasSelectedLanguage but hasCompletedIntro is false, they go to WelcomeScreen, then HowToUseThisAppScreen, then AppTabsScreen.
  • If hasSelectedLanguage is false, they go to ChooseYourLanguageScreen.

So with the code the way it is, in the return statement of RootStackScreen, I am rendering the screen that users should only see if they've set hasSelectedLanguage and hasCompletedIntro to true. I would like to find a way to check the correct conditions as outlined in the bullets above before rendering screens. So rather than rendering the (wrong lol, my fault) screen after checking hasSelectedLanguage, as I am now, I would check hasCompletedIntro immediately after that, and render screens on that basis.

Any help you could give would be hugely helpful :) thank you!

@jim-at-jibba
Copy link

Morning,

I have updated my example, splitting out the screen into their own stacks. Make organising them a little easier. Its here: https://github.com/jim-at-jibba/nav-demo/blob/master/App.js

Is there a reason why you are checking language selection on every app load. This feels like it should be in the "onboarding" and then stored for future use. You could always give the option to set the language after onboarding in the app somewhere (Ideally you would use the device language.)

Having it in onboarding would simplify your navigation as you could remove the choosenLanguageCheck.

You only need this <RootStack.Screen name="Home" component={AppTabsScreen} /> once as well. You can just route to that stack once the onboarding is done. It does not need to be in the onboarding stack too.

This is all a bit rambly. Lets talk more about you exact requirements and general project structure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment