I am passing a value from screen one
navigation.setParams({imageData:images[0]})
navigation.navigate('screenTwo')
OR
navigation.navigate('screenTwo',{imageData:images[0]})
But I am not able to access the value in screenTwo using
const screenTwo = ({navigation}) =>{
const itemId = navigation.getParam('imageData', 'NO-ID');
}
I am getting error
ERROR TypeError: navigation.getParam is not a function. (In 'navigation.getParam('imageData', 'NO-ID')', 'navigation.getParam' is undefined)
Any help would be greatly appreciated
"#react-navigation/drawer": "^5.12.5",
"#react-navigation/native": "^5.9.4",
"#react-navigation/stack": "^5.14.5",
I tried below code in the same page
navigation.setParams({imageData:images[0]})
console.log(navigation.params);
output : LOG undefined
No more getParam
Previously we could also use navigation.getParam('someParam', 'defaultValue') to get a param value. It addressed 2 things:
Guard against params being undefined in some cases
Provide a default value if the params.someParam was undefined or null
Official documentation: https://reactnavigation.org/docs/upgrading-from-4.x/#the-navigation-prop
Your solution
const screenTwo = ({navigation, route}) => {
const itemId = route.params?.imageData ?? 'NO-ID';
}
Online example: https://snack.expo.io/#vasylnahuliak/stackoverflow-68240142
import * as React from 'react';
import { Button, Text, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
const HomeScreen = ({ navigation }) => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details', { text: 'Hello, I am text from params' })}
/>
</View>
);
};
const DetailsScreen = ({route}) => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Details screen</Text>
<Text style={{padding: 40}}>{JSON.stringify(route.params)}</Text>
</View>
);
};
const RootStack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<RootStack.Navigator>
<RootStack.Screen name="HomeScreen" component={HomeScreen} />
<RootStack.Screen name="Details" component={DetailsScreen} />
</RootStack.Navigator>
</NavigationContainer>
);
}
solution for me worked in two-part:
problem of passing the param from first page to second page
solution: react-native navigation 5 undefined params
navigation.navigate('MainNavigationName', {
screen: 'ScreenNameToNavigate',
params: { propertyKey: propertyValue },
})
reading values from route
const itemId = route.params?.imageData ?? 'NO-ID';
thanks a lot Vasyl and Bora
Related
Okay so I'm just jumping into React Native and I'm going through the docs with the react-navigation package. Whenever a screen is pushed onto the stack, the animation goes from right-left by default—Also I'm noticing the back button is on the right side of the appbar instead of the left be default. Is this by design or have I set something up incorrectly?
Also ignore the FC I'm using, I know it's not recommended but I'm just getting a feel for RN 😅
See image and code below:
import { StatusBar } from "expo-status-bar";
import { Button, StyleSheet, Text, View } from "react-native";
import { createNativeStackNavigator } from "#react-navigation/native-stack";
import { BaseNavigationContainer } from "#react-navigation/native";
import { FC } from "react";
import { StackScreenProps } from "./Types";
const Home: FC<StackScreenProps> = ({ navigation }) => {
return (
<View style={styles.container}>
<Text>Hello World </Text>
<Button
title="Switch Page"
onPress={() => {
navigation.navigate("About");
}}
/>
</View>
);
};
const About: FC<StackScreenProps> = ({ navigation }) => {
return (
<View style={styles.container}>
<Text>Learn the Process First</Text>
<Button title="Go Back" onPress={() => navigation.goBack()} />
</View>
);
};
const Stack = createNativeStackNavigator();
export default function App() {
return (
<BaseNavigationContainer>
{/* #ts-ignore */}
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="About" component={About} />
</Stack.Navigator>
</BaseNavigationContainer>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});
Unable to navigate to new screen react native getting an error:
TypeError: undefined is not an object (evaluating 'navigation.navigate')
Can someone explain where I go wrong?
Below is the code I'm using.
const MessagesScreen = ({navigation}) => {
return (
<Container>
<FlatList
data={Messages}
keyExtractor={item=>item.id}
renderItem={({item}) => (
<Card onPress={() => navigation.navigate('Chat', {userName: item.userName})}>
<UserInfo>
<UserImgWrapper>
<UserImg source={item.userImg} />
</UserImgWrapper>
<TextSection>
<UserInfoText>
<UserName>{item.userName}</UserName>
<PostTime>{item.messageTime}</PostTime>
</UserInfoText>
<MessageText>{item.messageText}</MessageText>
</TextSection>
</UserInfo>
</Card>
)}
/>
</Container>
);
};
export default MessagesScreen;
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
},
});
it's seem that you forget to declare your screen in Navigator stack. something like this
<Stack.Screen
name="MessagesScreen"
component={MessagesScreen} />
this is an example from official page with
react navigation v5
import * as React from 'react';
import { View, Text } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
function HomeScreen() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
);
}
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;
I want to update the text after clicking button.
But couldn't find a way to do this.
The code is like:
import * as React from 'react';
import { View, Button, Text } from 'react-native';
import { NavigationContainer, CommonActions } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
function HomeScreen({ navigation }) {
const state = {
user: 'test',
};
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>{state.user}'s profile</Text>
<Button
title="Change user param"
onPress={() =>
navigation.dispatch({
...CommonActions.setParams({ user: 'Wojtek' }),
})
}
/>
</View>
);
}
const Stack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
Expo example
I've tried navigation.setParams() and this.setState(), they couldn't work with the code I attached above.
You have to use hooks in functional components. So the code would be something like this:
import * as React from 'react';
import { View, Button, Text } from 'react-native';
import { NavigationContainer, CommonActions } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
function HomeScreen({ navigation }) {
const [user, setUser] = React.useState('test');
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>{user}'s profile</Text>
<Button
title="Change user param"
onPress={() => setUser("keidakira") }
/>
</View>
);
}
const Stack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
Check it's working at Expo Link
I have an icon on the right side of my Header. When pressed I want to be transferred to another page. However, it comes up with an error.
This is my 'icon' screen:
import React, { Component } from 'react';
import { StyleSheet, View, Text, Image, TouchableOpacity } from 'react-native';
const Login = props => {
return (
<View style={{ flexDirection: 'row' }}>
<TouchableOpacity
onPress={() => {
props.navigation.navigate({routeName: 'Login'});}}>
<Image
source={{
uri:
'https://clipartart.com/images/login-icon-clipart-5.jpg',
}}
style={{
width: 40,
height: 40,
borderRadius: 40 / 2,
marginLeft: 15,
}}
/>
</TouchableOpacity>
</View>
);
}
export default Login;
This is my 'navigation' screen:
import {createStackNavigator} from 'react-navigation-stack';
import {createAppContainer} from 'react-navigation';
import React from 'react';
import Homepage from './screens/Homepage';
import Checkoutpage from './screens/Checkoutpage';
import Filterpage from './screens/Filterpage';
import Locationpage from './screens/Locationpage';
import Menupage from './screens/MenuPage';
import Welcomepage from './screens/Welcomepage';
import Loginpage from './screens/Loginpage';
import Finalpage from './screens/Finalpage';
import Login from './Components/Login';
const Navigation = createStackNavigator({
Home:Homepage,
Checkout: Checkoutpage,
Filter: Filterpage,
Location: Locationpage,
Menu: Menupage,
Welcome: Welcomepage,
Login: Loginpage,
Final: Finalpage
},
{
defaultNavigationOptions: {
headerRight:() => <Login/>
}
}
);
I'm very new to react-native. So if you found the problem, can you please explain thoroughly so I understand. Thank you!!
So it looks like you are expecting the navigation object to be part of the props passed to your <Login/> component. This object is only defined for screen components in react-navigate.
This means that you need to get access to the navigation functionality some other way. Luckily, this library provides you with the useNavigation() hook. So using that in your component would look something like:
// react-navigation v5+
import { useNavigation } from '#react-navigation/native';
const Login = () => {
const navigation = useNavigation();
return (
<View style={{ flexDirection: "row" }}>
<TouchableOpacity
onPress={() => {
navigation.navigate({ routeName: "Login" });
}}
>
<Image
source={{
uri: "https://clipartart.com/images/login-icon-clipart-5.jpg",
}}
style={{
width: 40,
height: 40,
borderRadius: 40 / 2,
marginLeft: 15,
}}
/>
</TouchableOpacity>
</View>
);
};
It seems to me you are using React Navigation v4.x , in order to use the useNavigation hook you need to upgrade to v5.x.
The navigation prop will be passed to all screens by default and you can use the useNavigation hook like #faelks suggested (if needed in other components).
UPGRADE TO v5 FIRST.
Here you have a little example for v5.x version:
import React from 'react'
import { Button, View, StyleSheet } from 'react-native'
import { NavigationContainer } from '#react-navigation/native'
import { createStackNavigator } from '#react-navigation/stack'
const Home = ({ navigation }) => (
<View style={styles.component}>
<Button title="Go to login" onPress={() => navigation.navigate('Login')} />
</View>
)
const Login = ({ navigation }) => (
<View style={styles.component}>
<Button title="Go back" onPress={() => navigation.goBack()} />
</View>
)
const Main = createStackNavigator()
const mainConfig = {
// configuration for this stack
initialRouteName: "Home",
}
export default props => (
<NavigationContainer>
<Main.Navigator {...mainConfig}>
<Main.Screen name="Home" component={Home} />
<Main.Screen name="Login" component={Login} />
{/* Other screens for this stack */}
</Main.Navigator>
</NavigationContainer>
)
const styles = StyleSheet.create({
component: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
})
If somebody can help me.
I'm sure that I miss something, but I can't see it.I'm trying to do navigation between 3 components and I create it with the documentation from the react-navigation page, I try a lot of different ways to do it, but always receive the same answer, so if somebody can see the mistake I do please tell me.
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import Header from './app/components/header/header'
import Main from './app/components/main/main';
import Data from './app/components/data/data';
import Grafic from './app/components/grafic/grafic';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import ButtonImage from './app/components/buttonImag/buttonImg'
import 'react-native-gesture-handler';
const Stack = createStackNavigator();
function MainScreen({ navigation }) {
return (
<ButtonImage onPress={() => navigation.navigate('Main')} heightV={40} widthV={40} itemImage={require('./app/resourse/home.png')} heightI={33} widthI={33} ></ButtonImage>
);
};
function DataScreen({ navigation }) {
return (
<ButtonImage onPress={() => navigation.navigate('Data')} heightV={40} widthV={40} itemImage={require('./app/resourse/datalist.png')} heightI={33} widthI={33} ></ButtonImage>
);
};
function GraficScreen({ navigation }) {
return (
<ButtonImage onPress={() => navigation.navigate('Grafic')} heightV={40} widthV={40} itemImage={require('./app/resourse/grafic.png')} heightI={33} widthI={33} ></ButtonImage>
);
};
const Footer = ({ navigation }) => {
return (
<View style={styles.header}>
<View style={styles.buttonPos}>
<MainScreen />
<DataScreen />
<GraficScreen />
</View>
</View>
)
};
function MyStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Main" component={() => <Main />} />
<Stack.Screen name="Data" component={() => <Data />} />
<Stack.Screen name="Grafic" component={() => <Grafic />} />
</Stack.Navigator>
);
}
const App = () => {
return (
<View style={{ flex: 1 }}>
<Header />
<NavigationContainer>
<MyStack />
</NavigationContainer>
<Footer />
</View>
);
}
const styles = StyleSheet.create({
header: {
backgroundColor: "#00BFFF",
height: 55
},
buttonPos: {
flex: 1,
flexDirection: 'row',
alignItems: "center",
justifyContent: "space-between",
padding: 7
},
conection: {
flex: 1,
flexDirection: 'row',
alignItems: "center",
justifyContent: "space-between",
padding: 7
}
});
export default App
What you need to do that is to use a Tab Navigator.
react-navigation v5 has 3 ways to do so:
createBottomTabNavigator
createMaterialBottomTabNavigator (very easy to customize)
createMaterialTopTabNavigator (with tabBarPosition: 'bottom')
Also you can customize the tabs by reading the documentation.
I made you a basic example using this last option:
import { SafeAreaView, View, Text, StyleSheet } from 'react-native'
import { NavigationContainer } from '#react-navigation/native'
import { createMaterialTopTabNavigator } from '#react-navigation/material-top-tabs'
import { createStackNavigator } from '#react-navigation/stack'
const Header = () => <View style={styles.header}><Text>Header title</Text></View>
const Main = () => <View style={styles.component}><Text>Main component</Text></View>
const Data = () => <View style={styles.component}><Text>Data component</Text></View>
const Grafic = () => <View style={styles.component}><Text>Grafic component</Text></View>
const footerConfig = {
tabBarPosition: 'bottom',
}
const Tabs = createMaterialTopTabNavigator()
const MyFooter = () => (
<Tabs.Navigator {...footerConfig}>
<Tabs.Screen name="Main" component={Main} />
<Tabs.Screen name="Data" component={Data} />
<Tabs.Screen name="Grafic" component={Grafic} />
</Tabs.Navigator>
)
const stackConfig = {
headerMode: 'none',
}
const Stack = createStackNavigator()
const MyStack = () => (
<Stack.Navigator {...stackConfig}>
<Stack.Screen name="Tabs" component={MyFooter} />
</Stack.Navigator>
)
export default () => (
<SafeAreaView style={styles.main}>
<Header />
<NavigationContainer>
<MyStack />
</NavigationContainer>
</SafeAreaView>
)
const styles = StyleSheet.create({
main: {
flex: 1,
},
header: {
height: 64,
width: '100%',
justifyContent: 'center',
alignItems: 'center',
},
component: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
})
EDIT:
You can use useNavigation hook inside your components. If you want to use your current configuration.
https://reactnavigation.org/docs/use-navigation/useNavigation
Also in order to send navigation props to components this:
<Stack.Screen name="Main" component={() => <Main />} />
should become:
<Stack.Screen name="Main" component={Main} />
// or
<Stack.Screen name="Main" component={props => <Main {...props} />} />
Go to you Main, Data, Grafic components and add {navigation} as your function parameter:
function Main({navigation}){
// rest of your codes
}
export default Main