Open another screen on button click in React Native app

Frankie picture Frankie · Jun 9, 2020 · Viewed 8.4k times · Source

I'm new with React Native.

I've got a list of photo albums in the AlbumScreen component. When a click on one album, I need to open another screen with all pictures inside the album.

Here is my main App component :

// Edit show imports for App.js

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';

import AlbumScreen from "./components/AlbumScreen"
import HomeScreen from "./components/HomeScreen"

// End of edit

const Tab = createMaterialBottomTabNavigator();

export default class App extends React.Component {

    render() {
        return (
            <NavigationContainer>

                <Tab.Navigator
                    initialRouteName="Home"
                    activeColor="#E0B1CB"
                    inactiveColor="#5E548E"
                    barStyle={{ backgroundColor: '#231942' }}
                >

                    <Tab.Screen
                        name="Home"
                        component={HomeScreen}
                        options={{
                            tabBarLabel: 'Home',
                            tabBarIcon: ({ color }) => (
                                <MaterialCommunityIcons
                                    name="home" 
                                    color={color} 
                                    size={26} 
                                />
                            ),
                        }}
                    />

                    <Tab.Screen
                        name="Album"
                        component={AlbumScreen}
                        options={{
                            tabBarLabel: 'My albums',
                            tabBarIcon: ({ color }) => (
                                <MaterialCommunityIcons 
                                    name="animation"
                                    color={color}
                                    size={26}
                                />
                            ),
                        }}
                    />

                </Tab.Navigator>

            </NavigationContainer>
        )
    }
}

Inside my AlbumScreen component, I inherit the "navigation" props with super(props). I've got a <Button /> to move to the another screen DetailsScreen :


// Edit show imports for AlbumScreen.js

import React from 'react';
import { Button, SafeAreaView, Navigator } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';

// End of edit

export default class AlbumScreen extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <SafeAreaView style={styles.container}>
                <Button
                    title="Go to Details"
                    onPress={() => this.props.navigation.navigate('DetailsScreen')}
                />
            </SafeAreaView>
        )
    }
}

and my DetailsScreen is given here (example from React Native Navigation doc) :

function DetailsScreen({ navigation }) {
    return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
            <Text>Details Screen</Text>
            <Button
                title="Go to Details... again"
                onPress={() => navigation.navigate('Details')}
            />
        </View>
    );
}

When I click on the <Button />, I have got the following error :

The action 'NAVIGATE' with payload {"name":"DetailsScreen"} was not handled by any navigator.

Do you have a screen named 'DetailsScreen'?

If you're trying to navigate to a screen in a nested navigator, see https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nested-navigator.

I miss something : can you help me to figure out why it does not switch to DetailsScreen please ? Many thanks.

Answer

Guruparan Giritharan picture Guruparan Giritharan · Jun 9, 2020

According to your code, the Details screen is not part of your navigation thats why you are getting the above error. You will need to change the code like below, to have a stack navigator and nest your TabNavigator inside it as the initial screen.

const Tab = createMaterialBottomTabNavigator();

function HomeTabs() {
  return (
    <Tab.Navigator
      initialRouteName="Home"
      activeColor="#E0B1CB"
      inactiveColor="#5E548E"
      barStyle={{ backgroundColor: '#231942' }}>
      <Tab.Screen
        name="Home"
        component={HomeScreen}
        options={{
          tabBarLabel: 'Home',
          tabBarIcon: ({ color }) => (
            <MaterialCommunityIcons name="home" color={color} size={26} />
          ),
        }}
      />

      <Tab.Screen
        name="Album"
        component={AlbumScreen}
        options={{
          tabBarLabel: 'My albums',
          tabBarIcon: ({ color }) => (
            <MaterialCommunityIcons name="animation" color={color} size={26} />
          ),
        }}
      />
    </Tab.Navigator>
  );
}

function DetailsScreen() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Details Screen</Text>
    </View>
  );
}

const Stack = createStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeTabs} />
        <Stack.Screen name="Details" component={DetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}