I have been running into an issue with navigating between screens in different files; I am assuming this is due to improperly exporting the functional components from one file to another. I created a snack for it: https://snack.expo.dev/#figbar/exportingbetweenscreens, and pasted the code in that below. Essentially, if 'DetailsScreen' is in app.js, the project becomes the sample navigation project, and works properly, however, when it is in this new file, the details screen is blank when navigated to.
App.js:
import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import {DetailsScreen} from './other';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
other.js:
import * as React from 'react';
import { Button, View, Text } from 'react-native';
function DetailsScreen() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
</View>
);
}
export default DetailsScreen;
DetailsScreen was exported as default, so it should be imported like this:
import DetailsScreen from './other';
and not this:
import {DetailsScreen} from './other';
Remove the curly braces and you will be good to go. Or alternatively, don't export DetailsScreen as default
Related
I know it is a basic question but when I search on the web the answer is always a single file mith multiple functions link here for exemple.
What I want is to use one function per file and multiple file ( I fought it would be simple like in HTML but when I look into it it seems so complicated! I only want to navigate between 2 pages!)
The link which you provide we only need to do the changes that we have to create new file and paste that function in new file like below
HomeScreen.js file is looks like this
import * as React from 'react';
import { Button, View, Text } from 'react-native';
Const HomeScreen = ({ navigation }) => {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
export default HomeScreen;
DetailsScreen.js file is looks like this
import * as React from 'react';
import { Button, View, Text } from 'react-native';
Const DetailsScreen = ({ navigation }) => {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button
title="Go to Details... again"
onPress={() => navigation.push('Details')}
/>
</View>
);
}
export default DetailsScreen;
And your app.js file looks like this.
import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import HomeScreen from ‘../HomeScreen’;
import DetailsScreen from ‘../DetailsScreen’
const Stack = createNativeStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
I have got "Screen1" where I create a string "blabla". According to the documentation, I can set it as a navigation parameter:
export default function Screen1() {
const navigation = useNavigation();
navigation.navigate("Screen2", { item: "blalbla" });
return (
<View>
<Text>Render some stuff</Text>
</View>
);
}
On Screen2 I should be able to access it with:
export default function Screen2({ route, navigation }) {
const { item } = route.params;
console.log(item);
return (
<View>
<Text>Render some stuff</Text>
</View>
);
}
Now, this returns:
TypeError: undefined is not an object (evaluating 'route.params.item')]
I also tried some other examples without success.
Referring to React-Native documentation: https://reactnavigation.org/docs/params/
I've created a Snack. Check this out.
Follow below steps to solve your problem
Create a Folder called navigation where your App.js is located.
Then inside this folder create a file called AppNavigator.js
Inside AppNavigator.js paste this
import React from 'react';
import { View } from 'react-native';
import { createStackNavigator } from '#react-navigation/stack';
import Screen1 from '../screens/Screen1';
import Screen2 from '../screens/Screen2';
const Stack = createStackNavigator();
function AppNavigator() {
return (
<Stack.Navigator>
<Stack.Screen name="Screen1" component={Screen1} />
<Stack.Screen name="Screen2" component={Screen2} />
</Stack.Navigator>
);
}
export default AppNavigator;
Now create another folder called screens where your App.js is located
Inside this folder create your two files Screen1.js and Screen2.js
They should look like this
Screen1.js -
import React from 'react';
import { View, StyleSheet, Text, Button } from 'react-native';
function Screen1({ navigation }) {
return (
<View style={styles.container}>
<Text>Screen 1</Text>
<Text onPress={() => navigation.navigate('Screen2', { item: 'blalbla' })}>
Press ME
</Text>
</View>
);
}
export default Screen1;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
Screen2.js -
import React from 'react';
import { View, StyleSheet, Text, Button } from 'react-native';
function Screen2({ route, navigation }) {
const { item } = route.params;
return (
<View style={styles.container}>
<Text>Screen 2</Text>
<Text onPress={() => navigation.navigate('Screen1')}>{item}</Text>
<Text onPress={() => navigation.navigate('Screen1')}>Press ME</Text>
</View>
);
}
export default Screen2;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
Now you should see route parameters inside Screen2
navigation object is probably not present in the screen
change Screen1({ navigation }) to Screen1(props) and do console.log(props) to check if you see a navigation object there
I am trying to do a small project myself to get to know React-Native.
I have 2 screens, and i want to navigate from my SplashScreen to HomeScreen by pressing on the button. But it gives me an error.
What should I add to get rid of the error?
Here are the codes
App.js
import 'react-native-gesture-handler'; // react-navigation, must be on top
import React from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import SplashScreen from "./src/screens/SplashScreen.js";
import HomeScreen from "./src/screens/HomeScreen.js";
const Stack = createStackNavigator();
const App = () => {
return (
// name is whatever you write
// initialRouteName is which screen you want as your initial
// when I add title, it will write it as title, not whats written in "name"
<NavigationContainer>
<Stack.Navigator initialRouteName="Intro" screenOptions={{title:"helllloo"}}>
<Stack.Screen name="Intro" component={SplashScreen} options={{title:"our intro"}} />
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
};
export default App;
HomeScreen.js
import React from "react";
import { View, Text } from "react-native";
const HomeScreen = () => {
return(
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
)
}
export default HomeScreen;
SplashScreen.js
import React from "react";
import { Text, View, Button } from "react-native";
import HomeScreen from "./HomeScreen";
const SplashScreen = ({ navigation }) => {
// without flex:1, it will center on that row, not on whole page
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Hello</Text>
<Button
title="Go to HomeScreen"
onPress = {() => navigation.navigate(HomeScreen)}
/>
</View>
)
}
export default SplashScreen;
you define route here <Stack.Screen name="Home" component={HomeScreen} />
the route name is "Home"
and route component HomeScreen
to navigate call navigation.navigate(route name not route component)
so replace this navigation.navigate(HomeScreen) with navigation.navigate("Home")
** I wanna to use react navigator on my app. Here I try to making two route and i want to see these. But i only see first route component. Theirs no button about 'def'. But copy those code from react navigator. i also found in snack emulator there also showing one route. does my code is wrong?? Advance thanks **
import { StatusBar } from 'expo-status-bar';
import React,{useState} from 'react';
import { StyleSheet, Text, View } from 'react-native';
import MultipleDateEntrys from './UI/Pages/MultipleDateEntrys.js'
import MaxCountrysEntry from './UI/Pages/MaxCountryData'
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
const Stack = createStackNavigator();
function HomeScreen() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>abc</Text>
</View>
);
}
function def() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>cde</Text>
</View>
);
}
export default function App() {
const title = useState('Corona Highlight')
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ title: 'Overview' }}/>
<Stack.Screen
name="Mon"
component={def}
options={{ title: 'def' }}/>
</Stack.Navigator>
{/* <Text style={styles.title}>{title}</Text> */}
</NavigationContainer>
);
}
When using a stack navigator only one screen would be shown which is the intended behavior.
You will have to navigate to the other screen using a button or some similar component.
All screens get a navigation prop you can use it to navigate.
In order to navigate to a screen you have to use the navigation.navigate("ScreenName"). Here the screen name would be the name that you provide in the stack when you initialize.
function HomeScreen({navigation}) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button title="Navigate" onPress={()=>navigation.navigate("Mon")}/>
<Text>abc</Text>
</View>
);
}
If you want both the screen in the same view you can use a tab navigator, which would allow you to switch screen using a tab
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Home"
component={HomeScreen}
options={{ title: 'Overview' }} />
<Tab.Screen name="Mon"
component={def}
options={{ title: 'def' }}/>
</Tab.Navigator>
);
}
At the start of my application, there is two tabs at the bottom of the screen (these tabs came in the template I downloaded from Expo for react js). I made a new screen, called homepage, and I want to now replicate those same tabs at the bottom, but I can't figure out how. I tried using a stack navigator but it did not work.
I want it to look like this
Here is my code for homescreen
import * as React from 'react';
import { StyleSheet, Button, TextInput } from 'react-native';
import EditScreenInfo from '../components/EditScreenInfo';
import { Text, View } from '../components/Themed';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import FAQ_Screen from './FAQ_Screen';
import NewsScreen from './NewsScreen';
import { createStackNavigator } from '#react-navigation/stack';
import BottomTabNavigator from '../navigation/BottomTabNavigator';
import NotFoundScreen from './NotFoundScreen';
const Stack = createStackNavigator();
export default function HomeScreen() {
return (
<View style={styles.container}>
<Text> Home </Text>
<select>
<option> Station 1 </option>
<option> Staton 2 </option>
</select>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
title: {
fontSize: 20,
fontWeight: 'bold',
},
separator: {
marginVertical: 30,
height: 1,
width: '80%',
},
});
You should declare tabs inside Tab.Navigator.
These screens can be separate .tsx or js files. I did using js, to be able to show using Expo. However, ts/js doesn't change the behavior.
I did a working example:
https://snack.expo.io/#mayconjcm/tab-navigation-%7C-react-navigation
You can also see the code here:
Home:
import * as React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import HomeTab from './Tab1';
import SettingsTab from './Tab2';
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeTab} />
<Tab.Screen name="Settings" component={SettingsTab} />
</Tab.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<MyTabs />
</NavigationContainer>
);
}
Tab1:
import * as React from 'react';
import { Text, View } from 'react-native';
const HomeTab = () => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
</View>
);
}
export default HomeTab;
Tab2:
import * as React from 'react';
import { Text, View } from 'react-native';
const SettingsTab = () => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
</View>
);
}
export default SettingsTab;