React Native: ListItem does nothing onPress - react-native

I am attempting to navigate from my current screen to the Profile screen and pass a parameter along using the ListItem onPress prop. The ListItems render properly onto the screen within a FlatList component, however, onPress does not navigate to the Profile screen.
import React from "react";
import { withNavigation } from '#react-navigation/compat';
import { StyleSheet, FlatList} from "react-native";
import { ListItem } from "react-native-elements";
import nerdProfiles from '../constants/nerdProfiles';
import { Block, Text } from 'galio-framework';
import argonTheme from "../constants/Theme";
import { TouchableOpacity } from "react-native-gesture-handler";
class NerdList extends React.Component {
renderItem = ({item}) => (
<TouchableOpacity>
<ListItem
title={
<Block>
<Text style={styles.names}>
{item.name}
</Text>
</Block>
}
subtitle={
<Block>
<Text style={styles.descriptions}>
{item.shortDescription}
</Text>
</Block>
}
leftAvatar={{ source: { uri: item.image } }}
bottomDivider
chevron
onPress={() => this.props.navigation.navigate('Profile', {test: 'Hello'})}
/>
</TouchableOpacity>
);
render() {
return (
<FlatList
data={nerdProfiles.bios}
renderItem={this.renderItem}
keyExtractor={item => item.id}
/>
);
};
};
export default withNavigation(NerdList);

Your code is correct, just try to put alert in the onPress function. Like,
onPress{()=>alert('ok')}
and check whether onPress is working or not. If yes it means there is problem with your navigate function. It cant find page Profile in navigation file. (Maybe spelling mistake of page name. Just check once what you've declare in your navigation file.)
If alert is also not working then try to remove onPress from ListItem and put it in the TouchableOpacity. Like
<TouchableOpacity onPress={()=>alert('ok')}>
then try to add navigate function
<TouchableOpacity onPress={() => this.props.navigation.navigate('Profile', {test: 'Hello'})}>
Here is my working small code
import React from "react";
import { StyleSheet, FlatList, Text, TouchableOpacity} from "react-native";
import { ListItem } from "react-native-elements";
import Font from 'expo-font'
class NerdList extends React.Component {
render() {
return (
<TouchableOpacity>
<ListItem
title={
<Text>
'item.name'
</Text>
}
subtitle={
<Text>
'item.shortDescription'
</Text>
}
bottomDivider
chevron
onPress={()=>alert('ok')}
/>
</TouchableOpacity>
);
}
}
export default NerdList;

When onPress function is provided to ListItem, it behaves like a Touchable component. So, no need to wrap the ListItem with a TouchableOpacity.
The parent TouchableOpacity captures onPress function and you cannot reach out the onPress function of the ListItem.

Related

Error: Couldn't find a navigation object. Is your component inside NavigationContainer?

I am trying to navigate from my login screen to the home screen using a pressable button. However, the code that I now have gives the following error: Couldn't find a navigation object. Is your component inside NavigationContainer?. The error is aimed on row 8 (const navigation = useNavigation();).
LoginButton.js:
import React, { Component } from "react";
import { View, Text, Image, Pressable, Button } from "react-native";
import { useNavigation } from "#react-navigation/native";
import styles from "./styles";
import HomeScreen from "../../screens/Home";
const LoginButton = () => {
const navigation = useNavigation();
return (
<View style={styles.container}>
<Pressable
onPress={() => navigation.navigate("Home")}
style={styles.button}
>
<Text style={styles.buttontext}>Login</Text>
</Pressable>
</View>
);
};
export default LoginButton;
The LoginButton is inserted as a component in the LoginItem inside the last <View. LoginItem.js:
import React from "react";
import { View, Text, Image } from "react-native";
import styles from "./styles";
import LoginButton from "../LoginButton";
import { createNativeStackNavigator } from "#react-navigation/native-stack";
const Stack = createNativeStackNavigator();
const LoginItem = (props) => {
return (
<View style={styles.logincontainer}>
{/* Background image of the login screen */}
<Image
source={require("../../../assets/images/blue-sky-start-screen.jpg")}
style={styles.loginbackground}
blurRadius={4}
></Image>
{/* Title of the login screen */}
<View style={styles.titlecontainer}>
<Text style={styles.companytitle}>BestelSnel</Text>
</View>
{/* Login button */}
<View style={styles.loginbutton}>
<LoginButton></LoginButton>
</View>
</View>
);
};
export default LoginItem;
useNavigation only works if your component is inside of a NavigationContainer and a Navigator like mentioned on the getting-started-page:
https://reactnavigation.org/docs/hello-react-navigation
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
HomeScreen would be your LoginItem
In my case, I got this error because autocomplete added the wrong import statement.
import { useNavigation } from "#react-navigation/core";
but the one I needed is:
import { useNavigation } from "#react-navigation/native";
Hope this helps anybody to save some minutes.
I had this issue as well, and the accepted answer did not work for me.
What I did get working on was importing the component I wanted to go to and using that in the navigate() call. Generally, this probably means just removing the quotes so your param to that function is a Component and not a String.
Given the code from the question, the code would be:
onPress={() => navigation.navigate(Home)}
Very similar to the original, just minus the quotes, as mentioned.
I was passing the params correctly also, but params had a react component in it. That's why it was giving this error.
// product should not have a react component
props.navigation.navigate(ROUTE_TEST, {product});

React navigation giving undefined

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

How do I create a modal when I click TouchableOpacity in React Native?

<TouchableOpacity>
<Text style={styles1.picturebutton}>Picture</Text>
</TouchableOpacity>
When I click "Picture", I want to get a modal(popup). How can I do so?
Thank you so much
You can do with something like this:
import React, {Component} from 'react'
import { View, Modal, TouchableOpacity, Text} from 'react-native'
export default class ViewPager extends Component {
constructor(props: Props) {
super(props)
this.state = {
IsModalVisible: false
}
}
render() {
return (
<View>
<Modal visible={this.state.IsModalVisible} onRequestClose={() => this.setState({IsModalVisibl: false})}>
<View>
<Text style={{color: (IsDarkThemeActive[0] ? 'white' : 'black')}}>Your modal Here</Text>
</View>
</Modal>
<TouchableOpacity onPress={() => this.setState({IsModalVisible: true})}>
<Text style={styles1.picturebutton}>Picture</Text>
</TouchableOpacity>
</View>
)
}
}
A button who changes the state of the visibility of the modal
You should take a look at : https://reactnative.dev/docs/modal its not that hard to accomplish.
Basically you set a state like showModal and say it is false by default but when you click your button it turns true and if u click it again it toggles back.
Then you just have to conditinally tell react native where it should render the modal if showModal is set to true.
Gl Faded.

How to re-render import component on state change

I have made two component (parent & child) & import the child component containing react-native modal
I have render child component after state change, it renders first time but on second time, it doesn't work.
Parent.js file is as follows:
import react, {Component} from 'react';
import { View, Text, TouchableOpacity} from 'react-native';
import ActionModal from './ActionModal';
export default class Parent extends Component {
constructor(props){
super(props);
this.state = { tabclicked: false }
}
actiontabclicked = () => {
this.setState({ tabclicked: true });
}
render(){
return (
<View>
<TouchableOpacity onPress={() => { this.actiontabclicked()} }>
<Text> MOVE</Text>
</TouchableOpacity>
{ (this.state.tabclicked) ? <ActionModal /> : null }
</View>
)
}
}
ActionModal.js file code
import React, {Component} from 'react';
import {Modal, Text, TouchableHighlight, View, Alert} from 'react-native';
export default class ActionModal extends Component {
constructor(){
super();
this.state = { modalVisible: true }
}
setModalVisible(visible) {
this.setState({modalVisible: visible});
}
render() {
return (
<View style={{marginTop: 22}}>
<Modal
animationType="slide"
transparent={false}
visible={this.state.modalVisible}
onRequestClose={() => { this.setModalVisible(!this.state.modalVisible)}}>
<View style={{marginTop: 22}}>
<View>
<Text>Hello World!</Text>
</View>
</View>
</Modal>
</View>
);
}
}
ActionModal opens first time but not second time, I think this is because state becomes true but after close modal it doesn't reset.
How can I achieve that ? Thanks in advance
You're not being so clear with what you want to achieve, if you want to achieve this behaviour of tapping > dismiss > tap again > shows
you should make something like this on your setModalVisible function:
setModalState = () => {
this.setState(prevState => ({
modalVisible: !prevState.modalVisible
})
}
This will change the state opposite to what it was. If you want to have more control maybe you can create two functions setModalOpen and setModalClosed
Maybe you can use props on the child component when onRequestClose is triggered to pass this function to the parent and there you can call setModalClosed, the way you have to do it is to make a callback with the given props (look for passing props to parent in react on the internet, it's quite simple)
Hope I could help

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>