1

I have my initial screen which works as expected:

 function MyTabs() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Schools" component={MainScreen} />
      <Tab.Screen name="Other" component={OtherScreen} />
    </Tab.Navigator>
  );
}


const Tab = createBottomTabNavigator();

function App() {
  return (
    <NavigationContainer>
      <MyTabs />
    </NavigationContainer>
  );
}

export default App;

It shows 3 option for screens on the bottom. When I am on the Main screen I see list of objects, I call them schools. Each school, I render inside a <TouchableOpacity> tag. Every time I click on this <TouchableOpacity> tag I want to navigate to a third screen called SchoolDetails.js. I have the following function, inside a component which I render from the MainScreen. I call this component SchoolsList:

const SchoolsList = ({ item, navigation }) => {
...
...
renderItem={({ item }) => {
          return (
            <TouchableOpacity
              onPress={() => navigation.navigate('Details')}
            >
              <Detail result={item} />
            </TouchableOpacity>
          );
        }}

My question is, how do I tell react that Details corresponds to SchoolDetails.js page? I tried to put it inside stacknavigator in the App.js page but it complained that I already have registered one bottomTabNavigator inside?

Right now, if I press on the <TouchableOpacity> tag I get the following error:

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

Do you have a screen named 'Details'?

newbie coder
  • 644
  • 5
  • 18
  • You can pass params to the `Details` screen and get the relevant school's details – emkarachchi Jan 16 '21 at 19:51
  • @emkarachchi That wasnt my issue. When I press on the I get the following error: The action 'NAVIGATE' with payload {"name":"Details"} was not handled by any navigator. Do you have a screen named 'Details'? – newbie coder Jan 16 '21 at 19:57
  • There should be an error as I don't see any `Details` screen inside your `Tab.Navigator`? – emkarachchi Jan 16 '21 at 20:00
  • @emkarachchi That is my question - I have not put because I dont want this screen to show up as a tab option on the bottom of the main page. How do I register this screen, without showing it on the main page? – newbie coder Jan 16 '21 at 20:02
  • Aha, I get the point now. You want to navigate to the `Details` screen by pressing an item on `Schools` page. Correct? – emkarachchi Jan 16 '21 at 20:04
  • @emkarachchi exactly :) – newbie coder Jan 16 '21 at 20:05

2 Answers2

3

You can do something like this.

You need to create a StackNavigator

import { createStackNavigator } from "@react-navigation/stack";
.....
.....
const Stack = createStackNavigator();

export const RootStack = () => {
  return (
    <Stack.Navigator initialRouteName="Schools">
      <Stack.Screen name="Schools" component={MainScreen}/>
      <Stack.Screen name="Details" component={DetailsScreen} />
    </Stack.Navigator>
  );
};

Then you can modify the Tab.Navigator to

 function MyTabs() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Root" component={RootStack} />  // Change this line
      <Tab.Screen name="Other" component={OtherScreen} />
    </Tab.Navigator>

Have a look at Nesting navigators in react-navigation docs

emkarachchi
  • 750
  • 1
  • 7
  • 18
0

I tried to create some basic app with parts of your coding: https://snack.expo.io/@adriaandebolle/reactnavigation5

It contains several ways to navigate:

  • Using ref
  • Using this.props.navigation
  • Passing navigation to function

The navigation prop is automatically added to a component of ReactNavigation.

As example I added a separate file Details.js which navigates using this.props.navigation.navigate like you wanted.

import * as React from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';

export default class DetailsScreen extends React.Component {
  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Text>Details!</Text>
        <Button title="Go back home! (Using this.props)" onPress={() => this.props.navigation.navigate('Schools')} />
      </View>
    );
  }
}

Within your main App.js file you import additional files and add them into whatever navigation structure you like (see answer emkarachchi):

import DetailsScreen from './Details';
Adriaan De Bolle
  • 225
  • 1
  • 3
  • 20