React navigation giving undefined - react-native

I am trying to make a back button in react native and using navigation.goBack() in the function component but if I console the navigation then it's giving me undefined
import React from 'react';
import {
Text,
StyleSheet,
Image,
View,
Dimensions,
TouchableOpacity,
} from 'react-native';
import backIcon from '../assets/back-black.png';
const {width: SCREEN_WIDTH, height: SCREEN_HEIGHT} = Dimensions.get('window');
const TitleHeader = ({navigation, title}) => {
// console.log("hello");
return (
<View style={[styles.customHeader]}>
<View style={[styles.headerLeft]}>
<TouchableOpacity onPress={() => navigation.goBack()}>
<Image source={backIcon} style={styles.headerIcon} />
</TouchableOpacity>
<Text style={[styles.font, styles.headerTitle]}>{title}</Text>
</View>
</View>
);
};
The rest of the code is working fine I am just getting an error in navigation so I add the important code only

React-navigation v5 provides hook useNavigation() returns the navigation prop of the screen it's inside.
Sample:
import * as React from 'react';
import { Button } from 'react-native';
import { useNavigation } from '#react-navigation/native';
function MyBackButton() {
const navigation = useNavigation();
return (
<Button
title="Back"
onPress={() => {
navigation.goBack();
}}
/>
);
}
In your code you need pass prop navigation to your component

Related

Why can I not navigate to another page from FlatList component in react native?

I'm not sure what's wrong here, as far as I can tell I am doing this correctly as it has worked everywhere else in my app. The only difference is that I'm trying to do this from a FlatList component. What is wrong with this? I've also tried putting {navigation} in renderMyItem instead of FLToyCard brackets, didn't work either. Error I'm getting is:
TypeError: undefined is not an object (evaluating 'navigation.navigate').
import { StyleSheet, Text, View, FlatList } from 'react-native'
import React from 'react'
import Toy from './Database'
import ToyCard from './ToyCard'
const FLToyCard = ({navigation}) => {
const headerComp = () => {
return(
<View style={{alignSelf: 'center'}}>
<Text style={{fontSize: 25, padding: 10}}>All Toys For Sale</Text>
</View>
)
}
const renderMyItem = ({item}) => {
return(
<View style={{flex: 1}}>
<ToyCard
name={item.name}
image={item.image}
price={item.price}
desc={item.desc}
seller={item.seller}
onPress={()=>navigation.navigate('SlugProduct')}
/>
</View>
)
}
return(
<View>
<FlatList
data={Toy}
renderItem={renderMyItem}
keyExtractor={(item)=>item.id}
numColumns={2}
ListHeaderComponent={headerComp}
/>
</View>
)
}
export default FLToyCard
This is my App.js:
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native'
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import SlugProduct from './Screens/SlugProduct';
export default function App() {
const Stack = createNativeStackNavigator()
return (
<NavigationContainer>
<Stack.Navigator initialRouteName='Login' >
// list of other pages
<Stack.Screen name="SlugProduct" component={SlugProduct} />
<Stack.Screen name='ViewToys' component={ViewToys}
</Stack.Navigator>
</NavigationContainer>
);
}
EDIT: heres the ViewToys page that FLToyCard is being input into. I've tried adding the onPress into both Views and FLToyCard but got the same error each time.
import { StyleSheet, Text, View, ScrollView} from 'react-native'
import React from 'react'
import FLToyCard from '../Components/FlatListCards'
const ViewToys = ({navigation}) => {
return (
<View style={{backgroundColor: '#ffce20', height: '100%'}}>
<View>
<FLToyCard />
</View>
</View>
)
}
export default ViewToys
The issue is that your not passing navigation props from screen ViewToys into component FLToyCard.
Try this
In ViewToys Screen:
import { StyleSheet, Text, View, ScrollView} from 'react-native'
import React from 'react'
import FLToyCard from '../Components/FlatListCards'
const ViewToys = ({navigation}) => {
return (
<View style={{backgroundColor: '#ffce20', height: '100%'}}>
<View>
<FLToyCard navigation={navigation}/>
</View>
</View>
)
}
export default ViewToys
change this <FLToyCard /> to this <FLToyCard navigation={navigation} />
and you are all done.
you are getting undefined in navigation in FLToyCard component that's why you are getting this error.
This error come when we do not put these mention in a page
import { NavigationContainer,useFocusEffect } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
So I think put above in every page once your problem will solve,

Getting "Invalid Hook Call" Error when trying to us Logout Button in Drawer.Navigator with useContext and useCallback

Im trying to implement a Logout button in the DrawerNavigator, which should logout via a function in my context and should then change the navigation with the useNavigation hook. However when it loads the component, I get the following error:
Here is my Code which im trying to execute:
import React, { useContext } from "react";
import { View, Text, Alert, StyleSheet, TouchableOpacity } from "react-native";
import {
DrawerContentScrollView,
DrawerItemList,
DrawerItem,
} from "#react-navigation/drawer";
import { useNavigation } from "#react-navigation/native";
import AuthContext from "../store/auth-context";
const CustomSidebarMenu = (props) => {
const navigation = useNavigation();
const authCtx = useContext(AuthContext);
return (
<View style={stylesSidebar.sideMenuContainer}>
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
<TouchableOpacity
style={stylesSidebar.buttonStyle}
onPress={() => {
authCtx.logout();
navigation.replace("Login");
}}
activeOpacity={0.5}
>
<Text style={stylesSidebar.buttonTextStyle}>Logout</Text>
</TouchableOpacity>
</DrawerContentScrollView>
</View>
);
};
export default CustomSidebarMenu;
useCallback code:
const logoutHandler = useCallback(async () => {
setToken(null);
await AsyncStorage.removeItem('token');
await AsyncStorage.removeItem('expirationTime');
if (logoutTimer) {
clearTimeout(logoutTimer);
}
}, []);
From apollo docs: Note that you cannot use the useNavigation hook inside the drawerContent since useNavigation is only available inside screens. You get a navigation prop for your drawerContent which you can use instead
Try props.navigation.replace("Login"); instead
Same issue you are facing on Github here as well: https://github.com/react-navigation/react-navigation/issues/7725

button onpress not working with own component

I have made a button component and want to add a onpress but it doesnt work. Can anyone explain me why its not working ?
Button Component.js
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity, Dimensions } from 'react-native';
const width = Dimensions.get('window').width;
const Button = ({ title }) => {
return (
<TouchableOpacity>
<Text>{title}</Text>
</TouchableOpacity>
)
};
export default Button;
Main.js
...
<Button onPress={handleSubmit} title="Jetzt registrieren"/>
...
you need to extract you onPress prop
const Button = ({ title,onPress }) => {
return (
<TouchableOpacity onPress={onPress}>
<Text>{title}</Text>
</TouchableOpacity>
)
};

React Native Modal CallBack - Passing Props to Parent

I am using React Native Modal and am having difficulty passing back the props from the Modal to the class that called the Modal.
I have tried with the onRequestClose() and onPress() and setting a prop for callback data googlePlacesPassedBackLocation but no success. I am trying to retrieve pastLocations from GooglePlaces. I can see in GooglePlaces that the location is being generated correctly. I am using the useState hook in both the Modal class and the GooglePlaces class.
I have read that this is a difficult thing to do as react doesn't really support it. Is it possible at all?
import {StyleSheet, View, Modal, TouchableOpacity, Text, TouchableHighlight, Button } from 'react-native';
Parent Component:
const RegisterLocationScreen = ({navigation}) => {
var [pastLocations, setPastLocations] = useState([]);
var [pastModalVisible, setModalPastVisible] = useState(false);
const closeModal = (timeFrame) => {
setModalPastVisible(false);
};
const openGooglePastModal = () => {
setModalPastVisible(true)
};
return (
<Modal visible={pastModalVisible} animationType={'slide'} onRequestClose={() => closeModal(pastLocations)}>
<View style={styles.modalContainer}>
<SafeAreaView style = {styles.safeAreaViewStyle} forceInset={{top: 'always'}}>
<GooglePlaces timePeriod="Past" googlePlacesPassedBackLocation={googlePlacesPassedBackLocation} />
<TouchableOpacity style = {styles.buttonContainer} onPress={()=> closeModal('Past')}>
<Text style={styles.buttonText} >
Close Modal
</Text>
</TouchableOpacity>
</SafeAreaView>
</View>
</Modal>
<TouchableOpacity style = {styles.buttonModal} onPress={() => openGooglePastModal()} >
<Text style={styles.buttonModalText} >
Past Locations
</Text>
</TouchableOpacity>
Child Component:
import React, {useState} from 'react';
import {StyleSheet } from 'react-native'
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
const API_KEY = '123omittedforsecurity';
const GooglePlaces = ({timePeriod}) => {
var [pastLocations, setPastLocations] = useState([]);
const updateLocationArray = (data, details) =>{
setPastLocations([
...pastLocations,
details.geometry.location
]);
};
return (
<GooglePlacesAutocomplete
placeholder={timePeriod}
onPress={(data, details) => {
updateLocationArray(data, details);
}}
..../>

Reusable Button with Image

So i'm new to react native and javascript, and i want to make a reusable button with image and i found this code
import React from 'react';
import { Image, TouchableOpacity } from 'react-native';
const ImgButtons = ({ onPress, img }) => {
return (
<TouchableOpacity onPress={onPress}>
<Image
source={require(img)}
/>
</TouchableOpacity>
);
};
export { ImgButtons };
and i call the component
<View style={styles.innerContainer}>
<ImgButtons
img={require('../assets/btn-reg-1.jpg')}/>
</View>
i got an error say Error: component/ImgButtons.js:Invalid call at line 9: require(img)
can somebody help me? Thanks :)
In you custom component I edited Image source check below:
import React from 'react';
import { Image, TouchableOpacity } from 'react-native';
const ImgButtons = ({ onPress, img }) => {
return (
<TouchableOpacity onPress={onPress}>
<Image
source={img}
/>
</TouchableOpacity>
);
};
export { ImgButtons };
Then you have to pass some method onPress
<View style={styles.innerContainer}>
<ImgButtons
img={require('../assets/btn-reg-1.jpg')}
onPress={()=>console.log('Action')}
/>
</View>