I am trying to use the navigation prop inside my Stack Navigator to open the drawer when the material icon is clicked. However when I click th button I recieve the error:
Undefined is not an object (evaluating navigation.openDrawer)
I am confused as I have passed the navigation prop into the 'App' function. Where am I going wrong here?
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import {NavigationContainer} from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
import {createDrawerNavigator} from '#react-navigation/drawer';
import HomeScreen from './src/screens/HomeScreen';
import SecondScreen from './src/screens/SecondScreen.js';
import {MaterialIcons} from '#expo/vector-icons';
const Drawer = createDrawerNavigator();
const Stack = createStackNavigator();
const TheDrawer = () => {
return(
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="SecondScreen" component={SecondScreen} />
</Drawer.Navigator>
);
}
const App = ({navigation}) =>{
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen
name="Home"component={TheDrawer}
options={{headerTitle:
<View>
<MaterialIcons
name='menu'
onPress={() => navigation.openDrawer()} size={28}
/>
</View>
}}
/>
<Stack.Screen name="SecondScreen" component={SecondScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default App;
The navigation prop only exist inside a Navigator, and different Navigators will have different navigation props (the Stack Navigator navigation will NOT have the openDrawer method, for example). I think that what you want to accomplish is this:
const App = () => {
return (
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen
name="Home"
component={HomeScreen}
options={({ navigation }) => ({
headerTitle: (
<View>
<MaterialIcons name="menu" onPress={() => navigation.openDrawer()} size={28}/>
</View>
),
})}
/>
<Drawer.Screen name="SecondScreen" component={SecondScreen} />
</Drawer.Navigator>
</NavigationContainer>
);
};
Or, if you want the menu button available on every page header:
const App = () => {
return (
<NavigationContainer>
<Drawer.Navigator
initialRouteName="Home"
screenOptions={({ navigation }) => ({
headerTitle: (
<View>
<MaterialIcons name="menu" onPress={() => navigation.openDrawer()} size={28} />
</View>
),
})}
>
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="SecondScreen" component={SecondScreen} />
</Drawer.Navigator>
</NavigationContainer>
);
};
Source: https://reactnavigation.org/docs/headers/
If you need to access more pages inside this two (Home, SecondScreen), you can create it like this:
const HomeScreen = () => {
<Stack.Navigator>
<Stack.Screen name="Home1" component={HomeScreen1} />
<Stack.Screen name="Home2" component={HomeScreen2} />
<Stack.Screen name="Home3" component={HomeScreen3} />
</Stack.Navigator>
}
Source: https://reactnavigation.org/docs/nesting-navigators
Related
I have few questions about React Navigation. I want to navigate from child screen to parent's sibling component, but I couldn't find a proper way for that. My navigation in the app looks like this:
Stack (Main)
LoginPage
Desk (DrawerNavigation)
Messages
MyAccount
Here I want to navigate to MyAccount, from Messages (Desk's child screen). How can I achieve that?
I'm using #react-navigation/stack, #react-navigation/drawer to config and useNavigation to redirect screen:
import * as React from "react";
import { Button, Text, View } from "react-native";
import { NavigationContainer, useNavigation } from "#react-navigation/native";
import { createStackNavigator } from "#react-navigation/stack";
import { createDrawerNavigator } from "#react-navigation/drawer";
const STYLE = {
flex: 1,
alignItems: "center",
justifyContent: "center",
width: "100%",
};
function LoginPage() {
const navigation = useNavigation();
return (
<View style={STYLE}>
<Text>LoginPage</Text>
<Button
title="Go to DrawerNav"
onPress={() => navigation.navigate("Desk")}
/>
</View>
);
}
function Messages() {
const navigation = useNavigation();
return (
<View style={STYLE}>
<Text>Messages</Text>
<Button
title="Go to MyAccount"
onPress={() => navigation.navigate("MyAccount")}
/>
</View>
);
}
function MyAccount() {
return (
<View style={STYLE}>
<Text>MyAccount</Text>
</View>
);
}
const Drawer = createDrawerNavigator();
const Desk = () => {
return (
<Drawer.Navigator initialRouteName="Messages">
<Drawer.Screen name="Messages" component={Messages} />
</Drawer.Navigator>
);
};
const Stack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="LoginPage">
<Stack.Screen name="LoginPage" component={LoginPage} />
<Stack.Screen
name="Desk"
component={Desk}
options={{ headerShown: false }}
/>
<Stack.Screen name="MyAccount" component={MyAccount} />
</Stack.Navigator>
</NavigationContainer>
);
}
I'm working at a ReactNative app and I want to create a drawer with right position.
Problem:
The problem is, if I change position to right a small part of it is always on the screen. When I open it, it takes the left position:
Drawer closed
Drawer open
react native drawer version:
"#react-navigation/drawer": "^6.1.8",
Drawer code:
const Drawer = createDrawerNavigator();
const DrawerContent = (props) => {
const { navigation } = props;
return (
<DrawerContentScrollView {...props} scrollEnabled={false}>
<Block flex={0.4} margin={20} bottom center>
<Image
source={require("../assets/icon.png")}
resizeMode="center"
style={styleDrawer.avatar}
/>
<Text title padding margin center>
{"دروس وملخصات باكالوريا "}
</Text>
</Block>
<Block>
<DrawerItem
label="الصفحة الرئيسية"
onPress={() => navigation.navigate("HomeScreen")}
style={styleDrawer.drawerItem}
labelStyle={styleDrawer.labelStyle}
icon={() => (
<AntDesign
name="home"
size={24}
color="black"
style={styleDrawer.icon}
/>
)}
/>
</Block>
</DrawerContentScrollView>
);
};
export default () => {
return (
<Drawer.Navigator
drawerType="slide"
overlayColor="transparent"
drawerStyle={styleDrawer.drawerStyles}
initialRouteName="Dashbord"
screenOptions={{
drawerPosition: "right",
headerShown: false,
activeBackgroundColor: "transparent",
activeTintColor: "white",
inactiveTintColor: "white",
}}
sceneContainerStyle={{
justifyContent: "center",
}}
drawerContent={(props) => {
return <DrawerContent {...props} />;
}}
>
<Drawer.Screen name="Screens">
{(props) => <Screens {...props} />}
</Drawer.Screen>
</Drawer.Navigator>
);
};
App.js Code:
import { NavigationContainer } from "#react-navigation/native";
import Drawer from "./src/Drawer";
import "react-native-gesture-handler";
import { Provider } from "react-redux";
import store from "./src/redux/store";
export default function App() {
return (
<Provider store={store}>
<NavigationContainer>
<Drawer />
</NavigationContainer>
</Provider>
);
}
I'm building an app that consists of public and private route.
The private route is as below:
Sign in (starting screen) --> (user signed in) --> Main Stack Screens (Home, Country, Communities, etc.)
The public route is as below:
Sign in (starting screen) --> (user not signed in) --> Main Stack Screens (Home, Country, Communities, etc.) with limited functions and content display to the user
In public route, I'm trying to add a login icon in the header of the Main Stack Screens, so users can be redirected back to the Auth flow and log in or sign up at any point of time when they wish to.
Here is my code for AuthStackNavigator.js:
import React from "react";
import { createStackNavigator } from "#react-navigation/stack";
import SignInScreen from "../screen/authentication/SignInScreen";
import SignUpScreen from "../screen/authentication/SignUpScreen";
import SignUpSuccessScreen from "../screen/authentication/SignUpSuccessScreen";
import PasswordResetScreen from "../screen/authentication/PasswordResetScreen";
const Stack = createStackNavigator();
const AuthStackNavigator = () => {
return (
<Stack.Navigator
initialRouteName="Sign In"
screenOptions={{ headerShown: false }}
>
<Stack.Screen name="Sign In" component={SignInScreen} />
<Stack.Screen name="Sign Up" component={SignUpScreen} />
<Stack.Screen name="Sign Up Success" component={SignUpSuccessScreen} />
<Stack.Screen name="Password Reset" component={PasswordResetScreen} />}
</Stack.Navigator>
);
};
export default AuthStackNavigator;
Here for MainNavigator.js:
import React, { useContext } from "react";
import { Platform, StyleSheet } from "react-native";
import { createStackNavigator } from "#react-navigation/stack";
import CountryScreen from "../screen/CountryScreen";
import CommunitiesScreen from "../screen/CommunitiesScreen";
import CommunityCreateScreen from "../screen/authorized/CommunityCreateScreen";
import CommunityHomeScreen from "../screen/CommunityHomeScreen";
import PostCreateScreen from "../screen/authorized/PostCreateScreen";
import CommentPostScreen from "../screen/authorized/CommentPostScreen";
import SearchBar from "../component/SearchBar";
import { generalconfig } from "../helper/generalconfig";
import { stylesconfig } from "../helper/stylesconfig";
import { AuthContext } from "../src/context/AuthContext";
import CustomProfileImg from "../component/CustomProfileImg";
import DefaultProfileIcon from "../component/DefaultProfileIcon";
import { Entypo } from "react-native-vector-icons";
import LoginIcon from "../component/LoginIcon";
const MainNavigator = () => {
const Stack = createStackNavigator();
const platform = Platform.OS;
const { width } = generalconfig.device;
const headerImageContainer = stylesconfig.global.headerImageContainer;
const { common, ios, aos } = stylesconfig.navigatorHeader;
const { profileImg, token } = useContext(AuthContext);
return (
<Stack.Navigator>
<Stack.Screen
name="Search Country"
component={CountryScreen}
options={{
title: "Search",
headerStyle: {
backgroundColor: common.backgroundColor,
},
headerTitleAlign: "left",
headerTintColor: common.color,
headerTitleStyle: {
fontFamily: platform === "ios" ? ios.fontFamily : aos.fontFamily,
fontWeight: platform === "ios" ? ios.fontWeight : aos.fontWeight,
fontSize: platform === "ios" ? ios.fontSize : aos.fontSize,
},
headerRight: () =>
profileImg ? (
<CustomProfileImg
activeOpacity={1.0}
onPress={() => {}}
src={{ uri: profileImg }}
style={headerImageContainer}
/>
) : (
<DefaultProfileIcon
activeOpacity={1.0}
onPress={() => {}}
iconSize={55}
iconPosition={{ height: 65, marginRight: 11 }}
/>
),
}}
/>
<Stack.Screen
name="Communities"
component={CommunitiesScreen}
options={{
headerStyle: {
backgroundColor: common.backgroundColor,
},
headerTintColor: common.color,
headerTitleStyle: {
fontFamily: platform === "ios" ? ios.fontFamily : aos.fontFamily,
fontWeight: platform === "ios" ? ios.fontWeight : aos.fontWeight,
fontSize: platform === "ios" ? ios.fontSize : aos.fontSize,
},
headerBackTitle: " ",
headerBackImage: () => (
<Entypo
name="controller-fast-backward"
size={23}
style={{ marginLeft: width - 376 }}
color={common.color}
/>
),
headerRight: () => (token ? <LoginIcon /> : null),
}}
/>
<Stack.Screen
name="Create Community"
component={CommunityCreateScreen}
options={{
headerTitle: "Create a Community",
}}
/>
<Stack.Screen name="Community Home" component={CommunityHomeScreen} />
<Stack.Screen name="Create Post" component={PostCreateScreen} />
<Stack.Screen name="Comment Post" component={CommentPostScreen} />
</Stack.Navigator>
);
};
const styles = StyleSheet.create({});
export default MainNavigator;
LoginIcon.js (component)
import React from "react";
import { TouchableOpacity } from "react-native";
import { stylesconfig } from "../helper/stylesconfig";
import { MaterialCommunityIcons } from "react-native-vector-icons";
import AuthStackNavigator from "../navigator/AuthStackNavigator";
const LoginIcon = () => {
const { common } = stylesconfig.navigatorHeader;
return (
<TouchableOpacity
onPress={() => {
<NavigationContainer>
<AuthStackNavigator />
</NavigationContainer>;
}}
>
<MaterialCommunityIcons
name="login"
size={23}
color={common.color}
style={{ marginRight: 15 }}
/>
</TouchableOpacity>
);
};
export default LoginIcon;
SignInScreen.js (partial code of the link navigating to Country Screen when it's pressed)
<CustomButtonLink
custBtnLinkName={browseAroundLabel}
style={[styles.spacing_Browse, styles.align]}
onNavigate={() => {
navigation.navigate(MainNavigator, { screen: "Search Country" });
}}
onNavigate={() => <MainNavigator />}
/>
CustomButtonLink.js (component)
const CustomButtonLink = ({ custBtnLinkName, style, onNavigate }) => {
return (
<TouchableOpacity style={style} onPress={onNavigate}>
<Text
style={[
stylesconfig.global.gtext,
generalconfig.platform.os === "ios"
? stylesconfig.ios.text
: stylesconfig.aos.text,
]}
>
{custBtnLinkName}
</Text>
</TouchableOpacity>
);
};
So my questions are:
How do I direct the user to the public route (Country Screen) if user is not authenticated?
Once user is directed to the public route (say Country Screen), how do I redirect him back to the AuthStackNavigator (Sign In screen) when he clicks the login icon?
I'm quite new to React Native so deeply appreciate it if anyone can help. Thanks!
For Authentication Flows you should be using conditional operations such as "&&", the ternary operator, etc.
The Way recommended by react navigation is to use the above, you can follow their guide here.
E.G.
isSignedIn ? (
<>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
<Stack.Screen name="Settings" component={SettingsScreen} />
</>
) : (
<>
<Stack.Screen name="SignIn" component={SignInScreen} />
<Stack.Screen name="SignUp" component={SignUpScreen} />
</>
)
Apart from #Abhishek Sah answer, it's recommended to detect user authentication state and navigator rerender accordingly. This will help when user successfully registered or logged out.
// Custom hook to continuously listen to user authentication state
const isSignedIn = useAth()
// listen to authentication state and rerender navigation accordingly
useEffect(()=>{
},[isSignedIn])
isSignedIn ? (
<>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
<Stack.Screen name="Settings" component={SettingsScreen} />
</>
) : (
<>
<Stack.Screen name="SignIn" component={SignInScreen} />
<Stack.Screen name="SignUp" component={SignUpScreen} />
</>
)
I'm using the drawer navigation from React Navigation v5. In my root file i've created the drawer navigator. Some of the screens inside of this navigator has a nested stack navigator. The first item is dashboard and the second item is Relations.
The problem is when I go to relations I don't get a back button for going to the first screen (Dashboard). Is it possible to add this to my relations screen?
Root code:
<NavigationContainer>
<DrawerNavigator.Navigator
drawerContent={(props) => (
<SidebarComponent {...props} user={this.props.device.user} />
)}
drawerPosition="right"
drawerStyle={{width: '90%', padding: 0, backgroundColor: 'red'}}>
{this.props.authenticated && this.props.device.api_key ? (
<>
<DrawerNavigator.Screen
name="Home"
options={{
headerShown: false,
icon: 'tachometer-alt',
category: 'dashboard',
}}
component={DashboardStack}
/>
<DrawerNavigator.Screen
name="Relations"
options={{
icon: 'address-book',
category: 'dashboard',
}}
component={RelationsStack}
/>
</>
) : (
<>
<DrawerNavigator.Screen
name="login"
options={{headerShown: false, gestureEnabled: false}}
component={LoginStack}
/>
</>
)}
</DrawerNavigator.Navigator>
</NavigationContainer>
Relation stack code:
import 'react-native-gesture-handler';
import React from 'react';
import {createStackNavigator} from '#react-navigation/stack';
import RelationsListScreen from '../RelationsListScreen';
import {colors} from '../../../assets/styles/variables';
const Stack = createStackNavigator();
function RelationsStack() {
return (
<Stack.Navigator>
<Stack.Screen
options={{
headerShown: true,
headerTintColor: '#FFF',
headerStyle: {
backgroundColor: colors.primary,
shadowColor: 'transparent',
},
}}
name="Relations"
component={RelationsListScreen}
/>
</Stack.Navigator>
);
}
export default RelationsStack;
You could create a stack navigator that is a screen of your drawer navigator (when the user is authenticated) which has Home and Relations as screens. I've called this navigator AuthenticatedNavigator in the example below:
const AuthenticatedStack = createStackNavigator();
// ...
const AuthenticatedNavigator = () => {
return (
<AuthenticatedStack.Navigator screenOptions={{headerShown: false}}>
<AuthenticatedStack.Screen
name="Home"
options={{
icon: 'tachometer-alt',
category: 'dashboard',
}}
component={DashboardStack}
/>
<AuthenticatedStack.Screen
name="Relations"
options={{
icon: 'address-book',
category: 'dashboard',
}}
component={RelationsStack}
/>
</AuthenticatedStack.Navigator>
);
};
function CustomDrawerContent(props) {
return (
<DrawerContentScrollView {...props}>
<DrawerItem
label="Home"
onPress={() => props.navigation.navigate('Home')}
/>
<DrawerItem
label="Relations"
onPress={() => props.navigation.navigate('Relations')}
/>
</DrawerContentScrollView>
);
}
function App() {
const authenticated = true;
return (
<NavigationContainer>
<DrawerNavigator.Navigator
drawerPosition="right"
drawerStyle={{width: '90%', padding: 0, backgroundColor: 'red'}}
drawerContent={(props) => <CustomDrawerContent {...props} />}>
{authenticated ? (
<DrawerNavigator.Screen
name="authenticated"
component={AuthenticatedNavigator}
/>
) : (
<DrawerNavigator.Screen
name="login"
options={{headerShown: false, gestureEnabled: false}}
component={LoginStack}
/>
)}
</DrawerNavigator.Navigator>
</NavigationContainer>
);
}
I've also used a custom drawer content component so the links in the drawer still work correctly after using the approach of creating another stack navigator. You can read more about providing a custom drawer component in the documentation here: https://reactnavigation.org/docs/drawer-navigator/#providing-a-custom-drawercontent.
I've left out some code and made authenticated a hardcoded value to simplify the example. Also be sure to import DrawerItem, DrawerContentScrollView from #react-navigation/drawer.
I using the flatlist to display a list of data. I wish to pass the data into another pages, but i have no idea which kind of navigation I shd use.
import Routes from './src/Routes';
export default class App extends Component<Props> {
render() {
return (
<View style={styles.container}>
<StatusBar
backgroundColor="#1c313a"
arStyle="light-content"
/>
<Routes/>
</View>
);
}
}
import React, { Component } from 'react';
import {StyleSheet, View, StatusBar,Text} from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import HomeScreen from '../pages/HomeScreen'
import YourActivitiesScreen from '../pages/YourActivitiesScreen'
import YourFavouriteScreen from '../pages/YourFavouriteScreen'
const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen
name="Home"
component={HomeScreen}
options={{ drawerLabel: 'Home' }}
/>
<Drawer.Screen
name="Your Activities"
component={YourActivitiesScreen}
options={{ drawerLabel: 'Your Activities' }}
/>
<Drawer.Screen
name="Your Favourite"
component={YourFavouriteScreen}
options={{ drawerLabel: 'Your Favourite' }}
/>
</Drawer.Navigator>
);
}
export default function SideMenu() {
return (
<NavigationContainer>
<MyDrawer />
</NavigationContainer>
);
}
import React, { Component } from 'react';
import {Router, Stack, Scene} from 'react-native-router-flux';
import Login from './pages/Login';
import Signup from './pages/Signup';
import SideMenu from './components/SideMenu'
export default class Routes extends Component {
render() {
return(
<Router>
<Stack key="root" hideNavBar>
<Scene key="login" component={Login} title="Login" initial/>
<Scene key="signup" component={Signup} title="Signup" />
<Scene key="home" component={SideMenu} title="HomeScreen" />
</Stack>
</Router>
);
}
}
import React, { Component } from 'react';
import {
StyleSheet,
View,
Text,
AsyncStorage,
TouchableOpacity,
FlatList,
Button,
} from 'react-native';
import DetailsScreen from './Details';
import { createDrawerNavigator, SafeAreaView } from 'react-navigation';
class HomeScreen extends Component{
constructor(props) {
super(props);
this.state = {
activitiesList: [],
}
};
renderItem = (item) => {
return (
<TouchableOpacity
onPress={() => {
console.log('test')
}}
>
<View style={styles.item}>
<Text style={styles.title}>{item.name}</Text>
</View>
</TouchableOpacity>
);
}
render(){
const listActivities = this.state.activitiesList
return (
<View>
<View style={styles.container}>
<Text style={styles.heading}>UPCOMING ACTIVITIES</Text>
</View>
<View>
<SafeAreaView>
<FlatList
data = {listActivities}
renderItem={({ item }) => this.renderItem(item)}
keyExtractor={item => item.id}
/>
</SafeAreaView>
</View>
</View>
)
}
}
I used the react-native-router-flux at the early part of system, which is login, signup and home. Now home display the flatlist, from the flatlist i have to make a onPress to navigate to another pages, the Actions in router-flux that i used before cannot work. Anyone have idea about it? or another better way navigate to to the details of flatlist?
First off, I'd refactor all the code to use just one kind of navigator (in this case, going for react-navigation). So, we will have your router-flux code combined with your
//Your routes screen
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
//... add missing imports
const Stack = createStackNavigator();
//this will be your old router-flux
const Root = () => {
return (
<Stack.Navigator>
<Stack.Screen name="login" component={Login} title="Login" initial/>
<Stack.Screen name="signup" component={Signup} title="Signup" />
<Stack.Screen name="home" component={SideMenu} title="HomeScreen" />
</Stack.Navigator>
)
}
const Drawer = () => {
return (
<Drawer.Screen
name="Home"
component={HomeScreen}
options={{ drawerLabel: 'Home' }}
/>
<Drawer.Screen
name="Your Activities"
component={YourActivitiesScreen}
options={{ drawerLabel: 'Your Activities' }}
/>
<Drawer.Screen
name="Your Favourite"
component={YourFavouriteScreen}
options={{ drawerLabel: 'Your Favourite' }}
/>
</Drawer.Navigator>
)
}
const AppContainer = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Root" component={Root} />
<Stack.Screen name="Drawer" component={Drawer} />
//import your Details screen to use inside component
<Stack.Screen name="Details" component={Details} />
</Stack.Navigator>
</NavigationContainer>
);
}
export default AppContainer
You will wrap your App.js component with this AppContainer. What we just did was to nest the navigations, your Home will be reached first and your drawer will be all in the same. Also, there is one missing stack in your code that is the one for the Details.
Right after here you are going to use all the actions from react-navigation. All the screens will receive a navigation props. Once you want to navigate from your Root, you will call the navigation just like props.navigation.navigate("Home").
The same will apply to navigate to your Detail screen from the FlatList.
//Your Home Screen
import React, { Component } from 'react';
import {
StyleSheet,
View,
Text,
AsyncStorage,
TouchableOpacity,
FlatList,
Button,
SafeAreaView
} from 'react-native';
class HomeScreen extends Component{
constructor(props) {
super(props);
this.state = {
activitiesList: [],
}
};
renderItem = (item) => {
return (
<TouchableOpacity
onPress={() => {
props.navigation.navigate("Details", { data: item })
console.log('test')
}}
>
<View style={styles.item}>
<Text style={styles.title}>{item.name}</Text>
</View>
</TouchableOpacity>
);
}
render(){
const listActivities = this.state.activitiesList
return (
<View>
<View style={styles.container}>
<Text style={styles.heading}>UPCOMING ACTIVITIES</Text>
</View>
<View>
<SafeAreaView>
<FlatList
data = {listActivities}
renderItem={({ item }) => this.renderItem(item)}
keyExtractor={item => item.id}
/>
</SafeAreaView>
</View>
</View>
)
}
}
Just added the navigation action to the code above. You have to access the params object in your Details Screen
//Details Screen
class DetailsScreen extends React.Component {
render() {
const { routes } = this.props;
return (
<View>
//Your component
<Text>{routes.data.name}</Text>
</View>
);
}
}
Just a side note. If you have a problem when navigating to a nested stack you can navigate this way using params
navigation.navigate(<YourParent>, {
screen: <YourDesiredScreen>,
params: { <YourObject> },
});
I hope it helps, at least as a guide. I didn't tested it, that's why I asked you to upload your code to expo.
I use react-navigation and couldn't be happier. All the navigation needed can be done with a simple:
this.props.navigation.navigate('ScreenName', {param1: 'Hello', param2: 'World'})
and then, when on the screen desired, get the param:
const { param1, param2 } = this.props.route.params;
More details here.
And, of course, if using function components it is even easier.
This example is form my 1st react-native-expo project but I hope that it will help you.
Bottom code is for two stack screens where I have PlayersTab screen and Player so main focus is to access Player with parms from PlayersTab using react-navigation
Navigation is in props object all you need is to destructor it in component const PlayersList = ({ navigation }) => {//your code}
import { View, Text } from 'react-native';
import React from 'react';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import PlayersList from '../personal_data_screen/PlayersList';
import PersonalDataScreenPlayer from'../personal_data_screen/PersonalDataScreenPlayer';
const Stack = createNativeStackNavigator();
const PersonalPlayerDataNavigator = ({ loginDataObject }) => {
return (
<Stack.Navigator>
<Stack.Screen options={{ headerShown: false }} name='PlayersTab'>
{(props) => (
<PlayersList {...props} loginDataObject={loginDataObject} />
)}
</Stack.Screen>
<Stack.Screen options={{ headerShown: false }} name='Player'>
{(props) => <PersonalDataScreenPlayer {...props} />}
</Stack.Screen>
</Stack.Navigator>
);
};
export default PersonalPlayerDataNavigator;
FlatList witch is in PlayersTab looks like this
<FlatList
data={Object.keys(friendList.data)}
renderItem={renderItem}
keyExtractor={keyExtractor}
navigation={navigation}
/>
const renderItem = ({ item }) => (
<Item
navigation={navigation}
account_id={friendList.data[item].account_id}
nickname={friendList.data[item].nickname}
/>
const Item = ({ nickname, account_id, navigation }) => (
<TouchableOpacity
onPress={() => navigation.navigate('Player', { account_id: account_id })}>
<View style={styles.itemView}>
<Text style={styles.playerNicknameText}>{nickname}</Text>
</View>
</TouchableOpacity>
And code for Player screen
import React from 'react';
import { View, Text } from 'react-native';
const PersonalDataScreenPlayer = ({ route }) => {
return (
<View
style={{
flex: 1,
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
}}>
<Text>{route.params.account_id}</Text>
</View>
);
};
export default PersonalDataScreenPlayer;