React Native touchable opacity margin expands the clickable area - react-native

So I have this code below, but when I add margins to my buttons in their styling like marginTop and marginLeft (shomeButton, mhomeButtom, and abthomeButton specifically), the clickable area for said button is expanded to whatever margins I have added. I tried using absolute positioning instead but that made it so it required many clicks for the buttons to work. Is there any fix? Thanks!
import React from 'react';
import { StyleSheet, View, Text, Image, TextInput, TouchableOpacity } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { LinearGradient } from 'expo-linear-gradient';
function HomeScreen({ navigation }) {
return (
<View style={styles.container}>
<LinearGradient colors={['#1155CC', 'transparent']} style={styles.background}/>
<Text style={styles.titleText}>GEO</Text>
<TouchableOpacity onPress={() => navigation.navigate('Single')}>
<LinearGradient colors={['#00FFFE', '#31f48e']} style={styles.singleButton}>
<Text style={styles.buttonText}> Single Player </Text>
</LinearGradient>
</TouchableOpacity>
<TouchableOpacity onPress={() => navigation.navigate('Multi')}>
<LinearGradient colors={['#00FFFE', '#31f48e']} style={styles.multiButton}>
<Text style={styles.buttonText}> Multi-Player </Text>
</LinearGradient>
</TouchableOpacity>
<TouchableOpacity onPress={() => navigation.navigate('About')}>
<LinearGradient colors={['#00FFFE', '#31f48e']} style={styles.creditButton}>
<Text style={styles.buttonText}> About </Text>
</LinearGradient>
</TouchableOpacity>
<Image style={styles.tinyLogo} resizeMode="cover" source={require('./assets/earth-icon.png')}/>
</View>
);
}
function SingleScreen({ navigation }) {
return (
<View style={styles.container}>
<LinearGradient colors={['#1155CC', 'transparent']} style={styles.background}/>
<Text style={styles.titleText}>GEO</Text>
<Text style={styles.underText}>Single</Text>
<Text style={styles.normText}>Last Answer:</Text>
<Text style={styles.normundText}>Arizona</Text>
<Text style={styles.normunaText}>Word: </Text>
<TextInput style={styles.input} placeholder="Your Answer" />
<Text style={styles.normunsText}>Incorrect/ Correct</Text>
<TouchableOpacity onPress={() => navigation.navigate('Home')}>
<LinearGradient colors={['#00FFFE', '#31f48e']} style={styles.shomeButton}>
<Text style={styles.buttonText}> Home </Text>
</LinearGradient>
</TouchableOpacity>
</View>
);
}
function MultiScreen({ navigation }) {
return (
<View style={styles.container}>
<LinearGradient colors={['#1155CC', 'transparent']} style={styles.background}/>
<Text style={styles.titleText}>GEO</Text>
<Text style={styles.underText}>Multi</Text>
<TouchableOpacity onPress={() => navigation.navigate('Home')}>
<LinearGradient colors={['#00FFFE', '#31f48e']} style={styles.mhomeButton}>
<Text style={styles.buttonText}> Home </Text>
</LinearGradient>
</TouchableOpacity>
</View>
);
}
function AboutScreen({ navigation }) {
return (
<View style={styles.container}>
<LinearGradient colors={['#1155CC', 'transparent']} style={styles.background}/>
<Text style={styles.titleText}>GEO</Text>
<Text style={styles.underText}>About</Text>
<Text style={styles.creditText}>Creators: Anonymous</Text>
<Text style={styles.credit2Text}>Version Number: 0.0.0</Text>
<TouchableOpacity onPress={() => navigation.navigate('Home')}>
<LinearGradient colors={['#00FFFE', '#31f48e']} style={styles.abthomeButton}>
<Text style={styles.buttonText}> Home </Text>
</LinearGradient>
</TouchableOpacity>
</View>
);
}
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home" screenOptions={{headerShown: false}}>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Single" component={SingleScreen} />
<Stack.Screen name="Multi" component={MultiScreen} />
<Stack.Screen name="About" component={AboutScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#4db4d7',
alignItems: 'center',
},
titleText: {
fontFamily: 'serif',
fontWeight: 'bold',
fontSize: 100,
color: '#31f48e',
},
underText: {
fontFamily: 'serif',
fontWeight: 'bold',
fontSize: 50,
color: '#31f48e',
},
singleButton: {
backgroundColor: '#31f48e',
borderRadius: 20,
elevation: 20,
height: 50,
marginTop: 40,
},
buttonText: {
fontFamily: 'serif',
fontWeight: 'bold',
fontSize: 30,
color: '#ffffff',
},
multiButton: {
backgroundColor: '#31f48e',
borderRadius: 20,
elevation: 20,
height: 50,
marginTop: 40,
marginBottom: 20,
},
tinyLogo: {
width: 380,
height: 380,
justifyContent: 'center',
alignItems: 'center',
},
abthomeButton: {
backgroundColor: '#31f48e',
borderRadius: 20,
elevation: 20,
height: 50,
marginTop: 210,
marginLeft: 225,
},
background: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
height: 500,
},
creditButton: {
backgroundColor: '#31f48e',
borderRadius: 20,
elevation: 20,
height: 50,
marginTop: 20,
marginBottom: 35,
},
creditText: {
fontFamily: 'serif',
fontSize: 25,
color: '#000000',
marginTop: 150,
},
credit2Text: {
fontFamily: 'serif',
fontSize: 25,
color: '#000000',
marginTop: 20,
},
credit3Text: {
fontFamily: 'serif',
fontSize: 25,
color: '#000000',
marginTop: 5,
},
mhomeButton: {
backgroundColor: '#31f48e',
borderRadius: 20,
elevation: 20,
height: 50,
marginTop: 550,
marginLeft: 230,
},
shomeButton: {
backgroundColor: '#31f48e',
borderRadius: 20,
elevation: 20,
height: 50,
marginTop: 220,
marginLeft: 230,
},
normText: {
fontFamily: 'serif',
fontSize: 30,
color: '#000000',
marginTop: 50,
},
normundText: {
fontFamily: 'serif',
fontSize: 30,
color: '#000000',
},
normunsText: {
fontFamily: 'serif',
fontSize: 30,
color: '#000000',
marginTop: 25
},
normunaText: {
fontFamily: 'serif',
fontSize: 25,
color: '#000000',
marginTop: 25
},
input: {
height: 40,
borderWidth: 2,
borderRadius: 10,
padding: 10,
marginTop: 25,
},
});
export default App;

Try adding style with flex 1, it worked for me.

Related

Touchable Opacity not working when nested inside View component but works if Touchable opacity is made the parent component to wrap other components

I have the following component created for showing an image card on screen. Inside this card there is an image that I am trying to make touchable, however, its does seem to work and when I try clicking on it, nothing happens.
But if I make the Touchable opacity as a parent component below, then the complete image card component becomes touchable and it works on screen. However, I do not want that and only want to target sub elements in this below card component. Not sure how to fix this!
import React, { useState } from "react";
import {
View,
Image,
Text,
StyleSheet,
TouchableOpacity,
} from "react-native";
const ImageCardView = ({
title,
category,
Price,
description,
imageUrl,
rating,
}) => {
return (
<View style={{ backgroundColor: "#d3c4de" }}>
<View style={styles.cardContainer}>
<RedCircle />
<TouchableOpacity onPress={() => navigation.navigate("showCase")}>
<Image
source={{
uri: imageUrl,
}}
style={styles.image}
/>
</TouchableOpacity>
<SeparatorVertical />
<View style={styles.textContainer}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.category}>{category}</Text>
<Text style={styles.price}>${Price}</Text>
<SeparatorHorizontal />
<Text numberOfLines={2} style={styles.description}>
{description}
</Text>
<View style={styles.rightBottom}>
<TouchableOpacity
style={styles.button}
onPress={() => setIsPressed(!isPressed)}
>
<Text>Add To Cart</Text>
</TouchableOpacity>
{/* {isPressed && (
<View
style={{
backgroundColor: "white",
paddingLeft: 16,
paddingRight: 16,
}}
>
<View
style={{
flexDirection: "row",
alignItems: "center",
paddingBottom: 12,
}}
>
<TouchableOpacity
disabled={!items.length}
onPress={removeItemFromBasket}
>
<Icon
name="minus-circle"
size={40}
color={items.length > 0 ? "#00CCBB" : "gray"}
/>
</TouchableOpacity>
<Text>{items.length}</Text>
<TouchableOpacity onPress={addItemToBasket}>
<Icon name="plus-circle" size={40} color="#00CCBB" />
</TouchableOpacity>
</View>
</View>
)} */}
<View style={styles.ratingContainer}>
{[...Array(5)].map((star, i) => {
const ratingValue = i + 1;
return (
<Text
key={i}
style={[
styles.star,
ratingValue <= rating && styles.filledStar,
]}
>
★
</Text>
);
})}
</View>
</View>
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
cardContainer: {
flexDirection: "row",
alignItems: "center",
backgroundColor: "white",
borderRadius: 5,
overflow: "hidden",
marginVertical: 10,
marginLeft: 3,
width: "98%",
height: 300,
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
image: {
width: 150,
height: 228,
resizeMode: "cover",
},
textContainer: {
paddingLeft: 10,
},
title: {
fontWeight: "bold",
fontSize: 20,
marginBottom: 10,
},
category: {
color: "#d6c3b9",
},
price: {
fontSize: 20,
fontWeight: "bold",
color: "#05c3fa",
},
description: {
flexDirection: "row",
flexWrap: "wrap",
fontSize: 15,
color: "#666",
marginBottom: 20,
},
ratingContainer: {
flexDirection: "row",
alignItems: "center",
},
button: {
alignItems: "center",
backgroundColor: "#5cb85c",
borderRadius: 5,
padding: 10,
},
rightBottom: {
flexDirection: "row",
},
star: {
fontSize: 18,
color: "#888",
},
filledStar: {
color: "#ffd700",
},
});
export default ImageCardView;
Without seeing the all the code, my suggestion is to make sure your TouchableOpacity is being imported from "react-native" and not from "react-native-gesture-handler" or some other npm package like "react-native-web".
Check the below code and logs, it's working fine:
import React, { useState } from "react";
import {
View,
Image,
Text,
StyleSheet,
TouchableOpacity,
} from "react-native";
const App = ({
title,
category,
Price,
description,
imageUrl,
rating,
}) => {
const [isPressed, setIsPressed] = useState(false)
return (
<View style={{ backgroundColor: "#d3c4de" }}>
<View style={styles.cardContainer}>
<TouchableOpacity onPress={() => {
console.log("on pressed!!!!")
navigation.navigate("showCase")
}
}>
<Image
source={{
uri: imageUrl,
}}
style={styles.image}
/>
</TouchableOpacity>
<View style={styles.textContainer}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.category}>{category}</Text>
<Text style={styles.price}>${Price}</Text>
<Text numberOfLines={2} style={styles.description}>
{description}
</Text>
<View style={styles.rightBottom}>
<TouchableOpacity
style={styles.button}
onPress={() => {
console.log("Add to card pressed!!!!")
setIsPressed(!isPressed)
}}>
<Text>Add To Cart</Text>
</TouchableOpacity>
{isPressed && (
<View
style={{
backgroundColor: "white",
paddingLeft: 16,
paddingRight: 16,
}}
>
<View
style={{
flexDirection: "row",
alignItems: "center",
paddingBottom: 12,
}}
>
<TouchableOpacity
disabled={!items.length}
onPress={removeItemFromBasket}
>
<Icon
name="minus-circle"
size={40}
color={items.length > 0 ? "#00CCBB" : "gray"}
/>
</TouchableOpacity>
<Text>{items.length}</Text>
<TouchableOpacity onPress={addItemToBasket}>
<Icon name="plus-circle" size={40} color="#00CCBB" />
</TouchableOpacity>
</View>
</View>
)}
<View style={styles.ratingContainer}>
{[...Array(5)].map((star, i) => {
const ratingValue = i + 1;
return (
<Text
key={i}
style={[
styles.star,
ratingValue <= rating && styles.filledStar,
]}
>
★
</Text>
);
})}
</View>
</View>
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
cardContainer: {
flexDirection: "row",
alignItems: "center",
backgroundColor: "white",
borderRadius: 5,
overflow: "hidden",
marginVertical: 10,
marginLeft: 3,
width: "98%",
height: 300,
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
image: {
width: 150,
height: 228,
resizeMode: "cover",
},
textContainer: {
paddingLeft: 10,
},
title: {
fontWeight: "bold",
fontSize: 20,
marginBottom: 10,
},
category: {
color: "#d6c3b9",
},
price: {
fontSize: 20,
fontWeight: "bold",
color: "#05c3fa",
},
description: {
flexDirection: "row",
flexWrap: "wrap",
fontSize: 15,
color: "#666",
marginBottom: 20,
},
ratingContainer: {
flexDirection: "row",
alignItems: "center",
},
button: {
alignItems: "center",
backgroundColor: "#5cb85c",
borderRadius: 5,
padding: 10,
},
rightBottom: {
flexDirection: "row",
},
star: {
fontSize: 18,
color: "#888",
},
filledStar: {
color: "#ffd700",
},
});
export default App;
For navigation, you need to get it referenced from parent props.
Thanks everyone. I got it fixed, in my case somehow the component was blocking the Touchable opacity, so included that inside my Touchable capacity to include the with the image and it started working

REACT NATIVE QUESTION TypeError: undefined is not an object (evaluating 'navigation.navigate') ...,

App.js (Login)
import * as React from 'react';
import {useState} from 'react';
import { Text, StyleSheet,
KeyboardAvoidingView, ScrollView, Image,
TextInput, TouchableOpacity, View } from 'react-native';
import { CheckBox } from 'react-native-elements';
import {Ionicons} from '#expo/vector-icons'
import {statusBar01} from './src/statusBar';
const Login = ({navigation}) => {
const [input, setInput] = useState('');
const [hidePass, setHidePass] = useState(true);
const [ischecked1, setIschecked1] = useState(true)
//const navigation = useNavigation();
return (
<KeyboardAvoidingView
style={styles.container}
>
<ScrollView>
<Image
source={require('./assets/logo.png')}
style={styles.logo}
/>
<Text style={styles.helloText}>
Olá de novo !
</Text>
<Text style={styles.welcomeText}>
Bem-vindo(a) de volta,
sentimos sua falta!
</Text>
<TextInput
style={styles.inputArea}
placeholder="Digite o e-mail"
/>
<TextInput
style={styles.inputArea}
placeholder="Senha"
value={input}
onChangeText={ (texto) => setInput(texto)}
secureTextEntry={hidePass}
/>
<TouchableOpacity style={styles.eye} onPress={ () => setHidePass(!hidePass) }>
<Ionicons name={hidePass ? 'eye' : 'eye-off'}
color="#A0D800" size={25}
/>
</TouchableOpacity>
<View style={styles.checkBoxStyle}>
<CheckBox
left
size={18}
checkedColor='#A0D800'
value={ischecked1}
checked={ischecked1}
onPress={() => setIschecked1(!ischecked1)}
containerStyle={{ backgroundColor: "transparent",
borderColor: "transparent", marginRight: 0}}
/>
<TouchableOpacity>
<Text style={styles.Connected}>
Manter-se conectado
</Text>
</TouchableOpacity>
<TouchableOpacity>
<Text style={styles.forgotPassword}>
Esqueci minha senha
</Text>
</TouchableOpacity>
</View>
<TouchableOpacity
style={styles.botao}
onPress={() => navigation.navigate('HomeScreen')}
>
<Text style={styles.botaoText}>Entrar</Text>
</TouchableOpacity>
</ScrollView>
</KeyboardAvoidingView>
);
}
const styles = StyleSheet.create({
container: {
flex: 2,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff'
},
logo: {
marginTop:50,
marginBottom: 80,
width: 150,
height: 40,
},
inputArea:{
marginTop: 30,
padding: 15,
height: 60,
width: 370,
borderColor: '#808080',
borderWidth: 1,
backgroundColor: '#fff',
fontSize: 16,
fontWeight: 'bold',
borderRadius: 15
},
botao: {
width: 350,
height: 60,
backgroundColor: '#000000',
marginTop: 35,
marginLeft: 8,
borderRadius: 15,
alignItems: 'center',
justifyContent: 'center',
},
botaoText: {
fontSize: 15,
fontWeight: 'bold',
color: '#fff'
},
helloText: {
fontSize: 40,
fontWeight: 'bold',
marginTop: 15,
color: '#000000',
marginEnd: 120,
marginTop: 8
},
welcomeText: {
fontSize: 16,
marginTop: 10,
marginEnd: 35,
marginVertical: 10,
color: '#808080',
},
forgotPassword: {
textDecorationLine: 'underline',
fontWeight: 'bold',
marginTop: 15,
marginBottom: 15,
marginLeft: 30,
fontSize: 12
},
Connected:{
textDecorationLine: 'underline',
fontWeight: 'bold',
marginTop: 15,
fontSize: 12,
marginRight: 55,
marginLeft: -5
},
checkBoxStyle:{
marginTop: 15,
flexDirection: 'row',
marginStart: -10
},
eye:{
alignSelf: 'flex-end',
bottom: 42,
right: 40
}
})
export default Login;
HomeScreen.js
import * as React from 'react';
import { useState } from 'react';
import { Text, View, ScrollView, KeyboardAvoidingView, Image, TouchableOpacity} from 'react-native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { Entypo, Feather } from 'react-native-vector-icons';
import SwitchSelector from "react-native-switch-selector";
import {Card} from 'react-native-shadow-cards';
import * as Progress from 'react-native-progress';
import { NavigationContainer } from '#react-navigation/native';
import statusBar01 from './src/statusBar';
import 'react-native-gesture-handler';
import {createStackNavigator} from 'react-navigation/stack'
import Login from '../../App';
//import { HomeScreen } from './src/screens/HomeScreen';
//import { TasksScreen } from './src/screens/TasksScreen';
//import { SettingsScreen } from './src/screens/SettingsScreen';
function TasksScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Tasks!</Text>
</View>
);
}
function HomeScreen() {
const options = [
{ label: "Active", value: "a" },
{ label: "New", value: "n" },
];
const [showHide, setShowHide] = useState(false);
return (
<KeyboardAvoidingView style={{
flex: 2,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff'
}}>
<ScrollView >
<Text style={{textAlign:'left', fontSize: 33,
fontWeight:'bold', paddingTop: 100,
paddingLeft: 20, bottom: 55}}>
{'Olá, \nUsuário!'}
</Text>
<Text style={{paddingLeft: 20,
color: '#808080', bottom: 80,
fontSize: 20 , paddingTop: 50}}>
Minhas tasks</Text>
<Image
source={require('./assets/images/user.jpeg')}
style={{marginTop:50,
width: 55,
height: 55,
borderRadius: 10,
top: -250,
left: 300,
borderColor: '#ECECEC',
borderWidth: 1
}
}
/>
<SwitchSelector
style={{width:390,paddingLeft: 15, bottom: 160}}
textColor={'#FFFFFF'}
selectedColor={'#000000'}
fontSize={15}
height={60}
bold
backgroundColor={'#000000'}
valuePadding={-1}
hasPadding
borderRadius={15}
options={options}
initial={0}
//onPress={value => console.log(`Call onPress with value: ${value}`)}
/>
<Card style={{ margin: 19, height: 170,
marginTop: -125}}>
<Feather name={'file-text'}
color={'#F2CB1D'}
size={20}
style={{paddingLeft: 20,
top: 20,}}/>
<Text
style={{paddingLeft: 50}}>Task 59788</Text>
<Entypo name={'controller-record'}
style={{paddingLeft: 270, bottom: 14
}}
color={'#007ACC'}
size={10}
/>
<Text
style={{paddingLeft: 290, bottom: 30}}
>Active</Text>
<Text style={{fontSize: 12,
paddingLeft: 20, bottom: 15
}}>App corporativo OnlineTeam</Text>
<Text style={{paddingLeft: 20,
fontSize: 20, bottom: 10}}>Criar telas no Figma</Text>
<Text style={{paddingLeft: 20,
fontSize: 12}}>Original Estimate: 4h</Text>
<Text style={{paddingLeft: 250,
bottom: 17, fontSize: 12}}>Completed: 2h</Text>
<Text style={{textAlign: 'left',
bottom: 10, fontSize: 10,
paddingLeft: 55}}>
0%</Text>
<Progress.Bar progress={0.1}
width={200}
color={'#A0D800'}
backgroundColor={'#ECECEC'}
borderColor={'transparent'}
height={10}
borderRadius={10}
style={{alignSelf: 'center'}}
bottom={20}
/>
<Text style={{textAlign: 'right',
fontSize: 10,bottom: 35,
paddingRight: 40}}>
100%</Text>
</Card>
<Card style={{ margin: 19, height: 170,
marginTop: -125, marginTop: 5}}>
<Entypo name={'bug'}
color={'#FF0000'}
size={20}
style={{paddingLeft: 20,
top: 20,}}/>
<Text
style={{paddingLeft: 50}}>Bug 59352</Text>
<Entypo name={'controller-record'}
style={{paddingLeft: 270, bottom: 14
}}
color={'#FF0000'}
size={10}
/>
<Text
style={{paddingLeft: 290, bottom: 30}}
>Issue</Text>
<Text style={{fontSize: 12,
paddingLeft: 20, bottom: 15
}}>Cargo Online Team</Text>
<Text style={{paddingLeft: 20,
fontSize: 20, bottom: 10}}>
Acusando duplicidade de contrato...</Text>
<Text style={{paddingLeft: 20,
fontSize: 12}}>Original Estimate: 4h</Text>
<Text style={{paddingLeft: 250,
bottom: 17, fontSize: 12}}>Completed: 2h</Text>
<Text style={{textAlign: 'left',
bottom: 10, fontSize: 10,
paddingLeft: 55}}>
0%</Text>
<Progress.Bar progress={0.1}
width={200}
color={'#A0D800'}
backgroundColor={'#ECECEC'}
borderColor={'transparent'}
height={10}
borderRadius={10}
style={{alignSelf: 'center'}}
bottom={20}
/>
<Text style={{textAlign: 'right',
fontSize: 10,bottom: 35,
paddingRight: 40}}>
100%</Text>
</Card>
</ScrollView>
</KeyboardAvoidingView>
);
}
function SettingsScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
</View>
);
}
export default function App() {
const Tab = createBottomTabNavigator();
return (
<NavigationContainer>
<Tab.Navigator
screenOptions={{
tabBarActiveTintColor: "#A0D800",
tabBarInactiveTintColor: "#FFFFFF",
//tabBarActiveBackgroundColor: "#FFFFFF",
//tabBarInactiveBackgroundColor: "#000000",
backgroundColor: "#FFFFFF",
headerShown: false,
tabBarSelectedItemStyle: {
borderBottomWidth: 2,
borderBottomColor: 'red',
},
tabBarStyle: [
{
display: "flex",
backgroundColor: "#000000",
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
height: 70,
overflow: 'hidden',
alignItems: 'center',
justifyContent: 'center',
},
null,
],
tabBarHideOnKeyboard: true,
tabBarLabelStyle:{
//fontSize: 20,
//fontWeight: 'bold',
backgroundColor: "#000000",
width: 60,
flex: 0.000004,
},
}}
>
<Tab.Screen name=" "
component={TasksScreen}
options={{
tabBarIcon: ({ color}) => (
<Entypo name="add-to-list"
size={30}
color={color}
/>
)
}}
/>
<Tab.Screen name=" "
component={HomeScreen}
options={{
tabBarIcon: ({ color}) => (
<Feather name="home"
size={30}
color={color}
/>
)
}} />
<Tab.Screen name=" "
component={SettingsScreen}
options={{
tabBarIcon: ({ color}) => (
<Feather name="settings"
size={30}
color={color}
/>
)
}}
/>
</Tab.Navigator>
</NavigationContainer>
);
}
I'm not managing to organize the code or implement a navigation on the login button for the home screen, someone helps me please???
I tried to create a Login.js and export it and the HomeScreen to the App.js but it also failed.
Could someone help me with the resolution so I can proceed with my code?
I need help whit this
I am a begginer dev
Please :( :( :(
Instead of relying on getting the navigation object as a prop, import useNavigation from react-navigation/core
import { useNavigation } from '#react-navigation/core';
export default function App(){
const navigation = useNavigation()
return(
<View>
<Button onPress={()=> navigation.navigate("homescreen")}/>
</View>
)
}
It seems that you did not import useNavigation. Add this to your code:
import { useNavigation } from '#react-navigation/native';
then declare a const within your login function:
const navigation = useNavigation();
then try it again. Also ensure you are calling the correct component name within the navigation.navigate('')
You should define names to your screens.
For example:
<Tab.Screen name="TasksScreen"
component={TasksScreen}
options={{
tabBarIcon: ({ color}) => (
<Entypo name="add-to-list"
size={30}
color={color}
/>
)
}}
/>
<Tab.Screen name="HomeScreen"
component={HomeScreen}
options={{
tabBarIcon: ({ color}) => (
<Feather name="home"
size={30}
color={color}
/>
)
}} />
<Tab.Screen name="SettingsScreen"
component={SettingsScreen}
options={{
tabBarIcon: ({ color}) => (
<Feather name="settings"
size={30}
color={color}
/>
Then you can navigate them with their names like navigation.navigate("HomeScreen")
You should name them carefully.
For detailed information and examples you can check:
https://reactnative.dev/docs/navigation
Have a good day!

getting the following error when using firestore Error: FIRESTORE (8.1.2) INTERNAL ASSERTION FAILED: Unexpected state

I'm currently working on an app and it was working fine for awhile...when I was signing up I add the users to firestore and it still worked but now whenever I use firestore in some other screen it keeps throwing the following error:
#firebase/firestore:, Firestore (8.1.2): FIRESTORE (8.1.2) INTERNAL ASSERTION FAILED: Unexpected state
Stack trace:
node_modules/react-native/Libraries/LogBox/LogBox.js:148:8 in registerError
node_modules/react-native/Libraries/LogBox/LogBox.js:59:8 in errorImpl
node_modules/react-native/Libraries/LogBox/LogBox.js:33:4 in console.error
node_modules/expo/build/environment/react-native-logs.fx.js:27:4 in error
http://127.0.0.1:19000/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&hot=false&minify=false:171277:27
and this is the code of the screen in which I'm getting errors
import React from 'react';
import {
View,
Text,
StyleSheet,
TextInput,
ScrollView,
TouchableOpacity,
Modal,
Platform,
ToastAndroid,
Alert,
} from 'react-native';
import DropDownPicker from 'react-native-dropdown-picker';
import { FontAwesome5, FontAwesome, Entypo } from '#expo/vector-icons';
import firebase from 'firebase';
import db from '../Config/Firebase';
import { CheckBox } from 'react-native-elements';
import Constants from 'expo-constants'
export default class Add extends React.Component{
state = {
allVisitsCompleted: false,
patientId: Math.floor(Math.random() * 1000000000) + 1,
patientName: '',
age: '',
address: '',
phoneNumber: '',
mobileNumber: '',
gender: '',
visitDate: '',
date: null,
modalVisible: false,
teethNumberModalVisible: false,
patient: [],
addPressed: false,
patientAdded: false,
};
onAddPatient = async () => {
firebase.firestore().collection("Patients").add({
patientName:this.state.patientName
})
}
render(){
var patientName = this.state.patientName
var patientId = this.state.patientId
return(
<ScrollView style={{ backgroundColor: '#F5FFFA' }}>
<View style={{ marginHorizontal: 19, marginTop: Constants.statusBarHeight}}>
<Text style={styles.header}>Patient name</Text>
<TextInput
placeholder=""
style={{
fontSize: 20,
fontWeight: '400',
height: 25,
borderBottomWidth: StyleSheet.hairlineWidth,
marginTop: 5,
}}
value={this.state.patientName}
onChangeText={(patientName) =>
this.setState({ patientName: patientName })
}
/>
</View>
<View style={{ marginHorizontal: 19, marginTop: 20 }}>
<Text style={styles.header}>Patient ID</Text>
<Text style={{ fontSize: 20 }}>{patientId}</Text>
</View>
<View style={{ marginHorizontal: 19, marginTop: 20 }}>
<Text style={styles.header}>Age</Text>
<TextInput
placeholder=""
style={{
fontSize: 20,
fontWeight: '400',
height: 25,
borderBottomWidth: StyleSheet.hairlineWidth,
marginTop: 5,
}}
value={this.state.age}
onChangeText={(age) => this.setState({ age: age })}
/>
</View>
<View style={{ marginHorizontal: 19, marginTop: 20 }}>
<Text style={styles.header}>Address</Text>
<TextInput
placeholder=""
style={{
fontSize: 20,
fontWeight: '400',
height: 25,
borderBottomWidth: StyleSheet.hairlineWidth,
marginTop: 5,
}}
value={this.state.address}
onChangeText={(address) => this.setState({ address: address })}
/>
</View>
<View style={{ marginHorizontal: 19, marginTop: 20 }}>
<Text style={styles.header}>Mobile number</Text>
<TextInput
placeholder=""
style={{
fontSize: 20,
fontWeight: '400',
height: 25,
borderBottomWidth: StyleSheet.hairlineWidth,
marginTop: 5,
}}
value={this.state.mobileNumber}
onChangeText={(mobileNumber) =>
this.setState({ mobileNumber: mobileNumber })
}
/>
</View>
<View style={{ marginHorizontal: 19, marginTop: 20 }}>
<Text style={styles.header}>Phone number</Text>
<TextInput
placeholder=""
style={{
fontSize: 20,
fontWeight: '400',
height: 25,
borderBottomWidth: StyleSheet.hairlineWidth,
marginTop: 5,
}}
value={this.state.phoneNumber}
onChangeText={(phoneNumber) =>
this.setState({ phoneNumber: phoneNumber })
}
/>
</View>
<View style={{ marginHorizontal: 19, marginTop: 20 }}>
<Text style={styles.header}>Gender</Text>
<TextInput
placeholder=""
style={{
fontSize: 20,
fontWeight: '400',
height: 25,
borderBottomWidth: StyleSheet.hairlineWidth,
marginTop: 5,
}}
value={this.state.gender}
onChangeText={(gender) => this.setState({ gender: gender })}
/>
</View>
<View style={{ marginHorizontal: 19, marginTop: 20 }}>
<Text style={styles.header}>All visits completed</Text>
<CheckBox
checkedColor="#0F0"
checkedTitle="Yes"
onPress={() =>
this.setState({
allVisitsCompleted: !this.state.allVisitsCompleted,
})
}
size={30}
title="No"
uncheckedColor="#F00"
checked={this.state.allVisitsCompleted}
checkedIcon="check"
uncheckedIcon="close"
/>
</View>
<View style={{ marginHorizontal: 25, marginVertical: 20 }}>
<TouchableOpacity
style={{
alignItems: 'center',
backgroundColor: '#62C7A1',
padding: 10,
borderRadius: 20,
}}
onPress={() => {
this.onAddPatient();
this.setState({ addPressed: true });
}}>
{this.state.patientAdded === true ? (
<PacmanIndicator color="#FFF" size={30} />
) : (
<Text
style={{
fontSize: 20,
color: 'white',
fontWeight: 'bold',
textTransform: 'uppercase',
}}>
Add
</Text>
)}
</TouchableOpacity>
</View>
</ScrollView>
)
}
}
const styles = StyleSheet.create({
header: {
fontSize: 13,
fontWeight: '200',
color: '#8e93a1',
textTransform: 'uppercase',
},
chooseDate: {
fontSize: 13, 
fontWeight: '600',
color: '#696969',
textTransform: 'uppercase',
},
});
If you have any Idea how to fix this please let me know...Thanks in advance!
I believe this might be a synchronicity issue, as your onAddPatient function is an async function but you are not awaiting firestore to add the documents, which generates an unexpected state. To fix it you just need to await for it, so:
onAddPatient = async () => {
await firebase.firestore().collection("Patients").add({
patientName:this.state.patientName
})
}

React Native close Modal that is opened by different component

Hello I am fairly new to React Native and am currently having an issue with my modal component. My modal component has two props, gameData and isModalVisible. In Home.js modal prop isModalVisible has the value of a state variable isVisible that gets changed to true when a certain TouchableOpacity is pressed. Then inside my FeaturedGameModal.js isModalVisible is set from props. The issue I am having is closing the modal. Opening the modal this way works fine, but how should I close the modal since its visibility is being controlled by props that are in Home.js? Any help would be greatly appreciated. I have been working on this for two days now and it is driving me crazy. Thanks! I will include my two files in case you want to more closely inspect my code.
Home.js:
import React from 'react';
import {
View,
Text,
Image,
SafeAreaView,
TouchableOpacity,
ActivityIndicator,
Linking,
ScrollView,
TouchableHighlight,
} from 'react-native';
import {homeStyles} from '../styles/homeStyles';
import {styles} from '../styles/styles';
import {createIconSetFromIcoMoon} from 'react-native-vector-icons';
import icoMoonConfig from '../../assets/fonts/selection.json';
import {fetchData} from '../functions/fetch';
import Modalz from '../modals/FeaturedGameModal';
const Icon = createIconSetFromIcoMoon(icoMoonConfig);
class Home extends React.Component {
myData = {};
constructor(props) {
super(props);
this.state = {
error: false,
isFetching: true,
featuredGameModal: false,
isVisible: false,
};
}
handleFeaturedGame = async () => {
this.setState({}, async () => {
try {
const featureGameData = await fetchData(
'http://dev.liberty.edu/templates/flames/json/json_appHomeFeed.cfm',
);
this.setState({
error: false,
featuredGameData: featureGameData,
isFetching: false,
});
} catch (e) {
this.setState({
error: true,
});
console.log(e.message);
}
});
};
handleFeaturedModal() {
this.setState({featuredGameModal: false});
}
componentDidMount() {
this.handleFeaturedGame();
}
render() {
const {featuredGameData} = this.state;
return this.state.isFetching ? (
<View style={styles.center}>
<ActivityIndicator size="large" color="#AE0023" />
</View>
) : (
<ScrollView>
<SafeAreaView>
<View style={homeStyles.featuredGameContainer}>
<View style={homeStyles.centerHor}>
<Image
style={homeStyles.logo}
source={require('../../assets/images/FlamesLogo.png')}
/>
</View>
<View style={homeStyles.gameTimeContainer}>
<Text style={homeStyles.gameTime}>
{featuredGameData.featuredGame.eventdate}
</Text>
<Text style={homeStyles.gameTime}>
{featuredGameData.featuredGame.eventtime}
</Text>
</View>
<TouchableOpacity
activeOpacity={0.6}
onPress={() => {
this.setState({isVisible: true});
}}>
<View style={homeStyles.contentContainer}>
<View style={homeStyles.contentLeft}>
<Text style={homeStyles.teamText}>
{featuredGameData.featuredGame.teamname}
</Text>
<Text style={homeStyles.opponentText}>
vs {featuredGameData.featuredGame.opponent}
</Text>
<Text style={homeStyles.locationText}>
<Icon size={12} name={'location'} />
{featuredGameData.featuredGame.location}
</Text>
</View>
<View style={homeStyles.contentRight}>
<Image
style={homeStyles.opponentLogo}
source={{
uri: featuredGameData.featuredGame.OpponentLogoFilename,
}}
/>
</View>
</View>
</TouchableOpacity>
<View style={homeStyles.allContent}>
<Modalz
gameData={this.state.featuredGameData.featuredGame}
isModalVisible={this.state.isVisible}
/>
<View style={homeStyles.contentContainerBottom}>
<View style={homeStyles.contentLeft}>
<TouchableOpacity
style={homeStyles.buyTicketBtn}
onPress={() =>
Linking.openURL(featuredGameData.featuredGame.buyTickets)
}>
<Text style={homeStyles.buyTicketBtnText}>Buy Tickets</Text>
</TouchableOpacity>
</View>
<View style={homeStyles.liveContainer}>
<Text style={homeStyles.live}>Experience Live:</Text>
<View style={homeStyles.liveIconsContainer}>
<Icon
style={{color: '#FFF', marginRight: 4}}
size={15}
name={'radio'}
/>
<Icon style={{color: '#FFF'}} size={12} name={'LFSN'} />
</View>
</View>
</View>
</View>
</View>
<View style={homeStyles.newsContainer}>
{featuredGameData.News.map((item, key) => (
<View
key={key}
style={[homeStyles.centerHor, homeStyles.newsCard]}>
<Image
style={homeStyles.newsImage}
source={{
uri: item.Thumbnail,
}}
/>
<Text style={homeStyles.headline}>{item.Headline}</Text>
<View style={homeStyles.teamNameView}>
<Text style={homeStyles.teamNameText}>{item.teamname}</Text>
<Text>{item.GameDate}</Text>
</View>
</View>
))}
</View>
</SafeAreaView>
</ScrollView>
);
}
}
export default Home;
FeaturedGameModal.js:
import React from 'react';
import {
Alert,
Modal,
StyleSheet,
Text,
TouchableHighlight,
View,
Image,
Dimensions,
TouchableOpacity,
SafeAreaView,
} from 'react-native';
import {createIconSetFromIcoMoon} from 'react-native-vector-icons';
import icoMoonConfig from '../../assets/fonts/selection';
import {homeStyles} from '../styles/homeStyles';
const Icon = createIconSetFromIcoMoon(icoMoonConfig);
const windowWidth = Dimensions.get('window').width;
export default class Modalz extends React.Component {
constructor(props) {
super(props);
this.state = {
teamName: props.gameData.teamname,
opponentName: props.gameData.opponent,
eventDate: props.gameData.eventdate,
liveAudioURL: props.gameData.LiveAudioURL,
liveStatsURL: props.gameData.LiveStatsURL,
videoURL: props.gameData.VideoURL,
opponentLogoURL: props.gameData.OpponentLogoFilename,
};
}
render() {
const {
opponentName,
teamName,
eventDate,
opponentLogoURL,
liveStatsURL,
liveAudioURL,
videoURL,
location,
} = this.state;
const {isModalVisible} = this.props;
return (
<View>
<View style={styles.centeredView}>
<Modal
animationType="slide"
transparent={true}
visible={isModalVisible}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
}}>
<SafeAreaView style={{flex: 1, backgroundColor: 'transparent'}}>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<Icon
style={styles.closeButton}
size={25}
name={'x'}
onPress={() => {}}
/>
<Text style={styles.upcomingGameTitle}>
{teamName} vs {opponentName}
</Text>
<Text style={styles.upcomingGameSubtitle}>{eventDate}</Text>
<View style={styles.facingLogosBlock}>
<View style={styles.leftTeamBlock} />
<View style={styles.rightTeamBlock} />
<View style={styles.vsTextWrapper}>
<Text style={styles.vsText}>VS</Text>
</View>
<View style={styles.logoWrapper}>
<Image
style={styles.facingLogoImg}
source={{
uri:
'https://www.liberty.edu/templates/flames/images/flamesMonogram.png',
}}
/>
<Image
style={styles.facingLogoImg}
source={{uri: opponentLogoURL}}
/>
</View>
</View>
<View>
<TouchableOpacity style={styles.buyTicketBtn}>
<Text style={styles.buyTicketBtnText}>Buy Tickets</Text>
</TouchableOpacity>
</View>
<View style={styles.buttonRow}>
<TouchableOpacity
style={{...styles.iconButton, ...styles.iconButtonLeft}}>
<Icon
style={styles.iconButtonIcon}
size={25}
name={'flag'}
onPress={() => {
this.toggleModal(!this.state.modalVisible);
}}
/>
<Text style={styles.iconButtonText}>Game Day</Text>
</TouchableOpacity>
<TouchableOpacity
style={{...styles.iconButton, ...styles.iconButtonRight}}>
<Icon
style={styles.iconButtonIcon}
size={25}
name={'stats'}
onPress={() => {
this.toggleModal(!this.state.modalVisible);
}}
/>
<Text style={styles.iconButtonText}>Live Stats</Text>
</TouchableOpacity>
</View>
<View style={styles.liveLinkBlock}>
<View style={styles.liveLinkLeft}>
<Icon
style={styles.iconButtonIcon}
size={18}
name={'LFSN'}
/>
<Text>The Journey 88.3 FM</Text>
</View>
<TouchableOpacity style={styles.liveButton}>
<Text style={styles.liveButtonText}>Listen Live</Text>
</TouchableOpacity>
</View>
<View style={styles.liveLinkBlock}>
<View style={styles.liveLinkLeft}>
<Icon
style={styles.iconButtonIcon}
size={18}
name={'espn3'}
/>
<Text>LFSN TV Production</Text>
</View>
<TouchableOpacity style={styles.liveButton}>
<Text style={styles.liveButtonText}>Watch Live</Text>
</TouchableOpacity>
</View>
</View>
</View>
</SafeAreaView>
</Modal>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
centeredView: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
modalView: {
flex: 1,
alignSelf: 'stretch',
backgroundColor: 'white',
borderTopLeftRadius: 20,
borderTopRightRadius: 20,
paddingTop: 14,
alignItems: 'center',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
openButton: {
backgroundColor: '#F194FF',
borderRadius: 20,
padding: 10,
elevation: 2,
},
closeButton: {
position: 'absolute',
right: 16,
top: 16,
color: '#000',
},
closeText: {
color: '#000',
fontWeight: 'bold',
textAlign: 'center',
fontSize: 20,
},
upcomingGameTitle: {
color: '#19191A',
fontSize: 18,
fontWeight: 'bold',
},
upcomingGameSubtitle: {
color: '#747676',
fontSize: 13,
fontWeight: 'bold',
marginBottom: 16,
},
modalText: {
marginBottom: 15,
textAlign: 'center',
},
facingLogosBlock: {
flexDirection: 'row',
position: 'relative',
alignItems: 'center',
},
facingLogoImg: {
width: 100,
height: 100,
resizeMode: 'contain',
flex: 1,
},
leftTeamBlock: {
width: 0,
height: 0,
backgroundColor: 'transparent',
borderStyle: 'solid',
borderRightWidth: 35,
borderTopWidth: 185,
borderRightColor: 'transparent',
borderTopColor: '#AE0023',
borderLeftColor: '#AE0023',
borderLeftWidth: windowWidth / 2,
left: 15,
zIndex: -1,
position: 'relative',
},
rightTeamBlock: {
width: 0,
height: 0,
backgroundColor: 'transparent',
borderStyle: 'solid',
borderLeftWidth: 35,
borderBottomWidth: 185,
borderBottomColor: '#461964',
borderRightColor: '#461964',
borderLeftColor: 'transparent',
borderRightWidth: windowWidth / 2,
right: 15,
zIndex: -1,
position: 'relative',
},
vsTextWrapper: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
justifyContent: 'center',
alignItems: 'center',
},
vsText: {
color: '#000000',
backgroundColor: '#FFFFFF',
padding: 5,
fontWeight: 'bold',
},
logoWrapper: {
position: 'absolute',
width: windowWidth,
height: 185,
top: 0,
left: 35,
flexDirection: 'row',
alignItems: 'center',
},
buyTicketBtn: {
marginTop: 24,
backgroundColor: '#AE0023',
borderRadius: 4,
paddingVertical: 20,
paddingHorizontal: 12,
width: windowWidth - 24,
},
buyTicketBtnText: {
fontSize: 21,
color: '#fff',
fontWeight: 'bold',
alignSelf: 'center',
textTransform: 'uppercase',
},
buttonRow: {
paddingVertical: 24,
paddingHorizontal: 12,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
iconButton: {
backgroundColor: '#F0F3F5',
borderRadius: 4,
paddingVertical: 14,
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
flex: 1,
},
iconButtonText: {
color: '#19191A',
fontWeight: 'bold',
fontSize: 16,
marginLeft: 10,
},
iconButtonIcon: {
color: '#000',
},
iconButtonLeft: {
marginRight: 6,
},
iconButtonRight: {
marginLeft: 6,
},
liveLinkBlock: {
padding: 12,
borderStyle: 'solid',
borderTopColor: '#F0F3F5',
borderTopWidth: 1,
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
},
liveButton: {
backgroundColor: '#F0F3F5',
borderRadius: 4,
paddingVertical: 14,
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
liveButtonText: {
color: '#19191A',
fontWeight: 'bold',
fontSize: 16,
},
liveLinkLeft: {
flex: 2,
},
});
You should create hideModal function in Home.js then pass it to Modalz component.
In Home.js, add this function:
hideModalz = () => {
this.setState({isVisible: true});
}
And pass this function to Modalz props:
<Modalz
gameData={this.state.featuredGameData.featuredGame}
isModalVisible={this.state.isVisible}
hide={hideModalz}
/>
In Modalz, call this.props.hide(); if you want to hide modal.

How to put text on the ParallaxImage

I am using react-native-snap-carousel.
How can I have the text on the image?
<View style={styles.item}>
<ParallaxImage
source={{ uri: item.illustration }}
containerStyle={styles.imageContainer}
style={styles.image}
parallaxFactor={0.35}
{...parallaxProps}
/>
</View>
<View style={styles.textContainer}>
<Text styke={styles.title}>{item.title}</Text>
<Text style={styles.subtitle}>{item.subtitle}</Text>
</View>
Styles:
const styles = StyleSheet.create({
item: {
width: screenWidth - 60,
height: screenWidth - 250
},
imageContainer: {
flex: 1,
marginBottom: Platform.select({ ios: 0, android: 1 }), // Prevent a random Android rendering issue
backgroundColor: 'white',
borderTopLeftRadius: 5,
borderTopRightRadius: 5
},
image: {
...StyleSheet.absoluteFillObject,
resizeMode: 'cover'
},
textContainer: {
justifyContent: 'center',
paddingTop: 20 - 8,
paddingBottom: 20,
paddingHorizontal: 16,
borderBottomLeftRadius: 5,
borderBottomRightRadius: 5,
backgroundColor: colors.gray3
},
title: {
color: colors.black,
fontSize: 13,
fontWeight: 'bold',
letterSpacing: 0.5
},
subtitle: {
marginTop: 6,
color: colors.gray,
fontSize: 12,
fontStyle: 'italic'
}
});
Add a bottom of a value such as
return (
<View style={styles.item}>
<ParallaxImage
source={item.thumbnail}
containerStyle={styles.imageContainer}
style={styles.image}
parallaxFactor={0.4}
{...parallaxProps}
/>
<View style={{bottom: 40}}>
<Text style={{color:'white', fontSize: scale(20), }}>
{item.title}
</Text>
</View>
</View>
Could you try this?
<View style={styles.item}>
<ParallaxImage
source={{ uri: item.illustration }}
containerStyle={styles.imageContainer}
style={styles.image}
parallaxFactor={0.35}
{...parallaxProps}
/>
<Text styke={styles.title}>{item.title}</Text>
<Text style={styles.subtitle}>{item.subtitle}</Text>
</View>
....
<Carousel
...
itemWidth={screenWidth - 60}
/>
...
item: {
width: screenWidth - 60,
height: screenWidth - 60
}