1

This is my App.js

import React from "react";

import Menu from "./components/Menu";

import HomeScreen from "./views/HomeScreen";
import SecondScreen from "./views/SecondScreen";

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

export default function App() {
  return (
    <Container>
        <NavigationContainer>
          <Stack.Navigator>
            <Stack.Screen
              name="Home"
              component={HomeScreen}
            />
            <Stack.Screen name="Second" component={SecondSCreen} />
          </Stack.Navigator>
        </NavigationContainer>
      <Menu></Menu>
    </Container>
  );
}

It works, because it shows the HomeScreen on default, but I want to navigate to the second screen via the Menu-component:

import React from "react";
import { View, Text, TouchableOpacity } from "react-native";

class Menu extends React.Component {
  render() {
    return (
      <View>
        <TouchableOpacity
          onPress={() => {
            alert("Hi");
          }}
        >
          <Text>HomeScreen</Text>
        </TouchableOpacity>

        <TouchableOpacity
          onPress={() => {
            navigation.navigate("Second");
          }}
        >
          <Text>Screen 2</Text>
        </TouchableOpacity>
      </View>
    );
  }
}

export default Menu;

The component is visible, but when I click on the second button I expect the SecondScreen to be openend. But I get this error:

Can't find variable: navigation

What am I missing?

3
  • You are trying to access navigation outside navigation check this answer stackoverflow.com/a/62700646/1435722 Commented Jul 5, 2020 at 13:59
  • @GuruparanGiritharan but how can I (re)use that to make my Menu.js work? Commented Jul 5, 2020 at 14:07
  • check my answer Commented Jul 5, 2020 at 14:13

1 Answer 1

3

You should use the navigationRef for this scenario, as your menu is outside the navigation container

import { NavigationContainer } from '@react-navigation/native';
import { navigationRef } from './RootNavigation';

  export default function App() {
  return (
    <Container>
        <NavigationContainer ref={navigationRef}>
          <Stack.Navigator>
            <Stack.Screen
              name="Home"
              component={HomeScreen}
            />
            <Stack.Screen name="Second" component={SecondSCreen} />
          </Stack.Navigator>
        </NavigationContainer>
      <Menu></Menu>
    </Container>
  );
}

// RootNavigation.js

import * as React from 'react';

export const navigationRef = React.createRef();

export function navigate(name, params) {
  navigationRef.current?.navigate(name, params);
}

In menu js,

import {navigate} from 'RootNavigation';

class Menu extends React.Component {
  render() {
    return (
      <View>
        <TouchableOpacity
          onPress={() => {
            alert("Hi");
          }}
        >
          <Text>HomeScreen</Text>
        </TouchableOpacity>

        <TouchableOpacity
          onPress={() => {
            navigate("Second");
          }}
        >
          <Text>Screen 2</Text>
        </TouchableOpacity>
      </View>
    );
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot! Can I extend this also to get route parameters? Now I do this: navigate("Sheep", { slug: card.slug });, but I cannot access the slug parameter
it should be available in route.params.slug in 'Sheep' screen, like normal route prop

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.