Search code examples
react-nativereact-navigationreact-navigation-stackreact-navigation-v5

Navigate to un-rendered screen inside stack navigation


I have the following structure for my app (ignore syntaxes in the below structure, using it just to present the overall organization of the navigation) and am using react navigation v5 for my navigation.

<TabNavigator>
  <Tab1 label="Books">
    <StackNavigator>
      <Screen1 name=books>
      <Screen2 name=bookDetails>
    </StackNavigator>
  </Tab1>
  <Tab2 label="Authors">
    <StackNavigator>
      <Screen1 name=authors>
      <Screen2 name=authorDetails>
    </StackNavigator>
  </Tab2>
</TabNavigator>

When the app loads, it shows a list of books in a FlatList, clicking on each takes to the bookDetails screen. On that screen, it shows more details about the book and an image of the book author. Clicking on the author image should take to the authorDetails screen, but that does not work since the second stack navigator is not rendered and navigation does not know about it.

Looked through the react navigation documentation including nested navigators and searched everywhere but have not found a solution.

Is there a trick to get it working or do I need to restructure my navigation tree to a different one?


Solution

  • You can navigate without a problem.

    You have a full example here:

    import React from 'react'
    import { View, Text, Button, StyleSheet } from 'react-native'
    import { NavigationContainer } from '@react-navigation/native'
    import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
    import { createStackNavigator } from '@react-navigation/stack'
    
    const Tab = createBottomTabNavigator()
    const Stack = createStackNavigator()
    
    const Books = ({ navigation }) => (
        <View style={styles.view}>
            <Button
                title="Go to details"
                onPress={() => navigation.navigate('BookDetails')}
            />
        </View>
    )
    const BookDetails = ({ navigation, id }) => (
        <View style={styles.view}>
            <Button
                title="Author name"
                onPress={() => navigation.navigate('AuthorsStack',{screen:'AuthorDetails',params:{id: "Author id"}})}
            />
        </View>
    )
    
    const Authors = () => <View style={styles.view} />
    const AuthorDetails = ({ navigation, route }) => (
        <View style={styles.view}>
            <Text>{route.params.id}</Text>
            <Text>Other details</Text>
            <Button
                title="Go to book details"
                onPress={() => navigation.navigate('BooksStack',{screen:'BookDetails',params:{id: "Book id"}})}
            />
        </View>
    )
    
    const BooksStack = () => (
        <Stack.Navigator>
            <Stack.Screen name="Books" component={Books} />
            <Stack.Screen name="BookDetails" component={BookDetails} />
        </Stack.Navigator>
    )
    
    const AuthorsStack = () => (
        <Stack.Navigator>
            <Stack.Screen name="Authors" component={Authors} />
            <Stack.Screen name="AuthorDetails" component={AuthorDetails} />
        </Stack.Navigator>
    )
    
    const TabNavigator = () => (
        <Tab.Navigator>
            <Tab.Screen name="BooksStack" component={BooksStack} />
            <Tab.Screen name="AuthorsStack" component={AuthorsStack} />
        </Tab.Navigator>
    )
    
    
    export default props => (
        <NavigationContainer>
            <TabNavigator />
        </NavigationContainer>
    )
    
    const styles = StyleSheet.create({
        view: {
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center'
        }
    })