Invariant Violation: `value` prop must be an instance of Date object - react-native

I am building a form and this 2 things are behaving bad,
when i press on either of the button and select any date or time, it shoes the above mentioned error from the header as
'Invariant Violation: value prop must be an instance of Date object'
Moreover it also crashes the app builded up on the device emulator
import RNDateTimePicker from '#react-native-community/datetimepicker';
import React,{ useState } from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
export default function App() {
const [datePicker,setDatePicker] = useState(false)
const [datei, setDatei] = useState(new Date())
const [timePicker,setTimePicker] = useState(false)
const [time,setTime] = useState(new Date(Date.now()))
function showDatePicker(){
setDatePicker(true)
}
function showTimePicker(){
setTimePicker(true)
}
function OnDateSelected(datei){
setDatei(datei);
setDatePicker(false)
}
function onTimeSelected(time){
setTime(time);
setTimePicker(false)
}
return (
<View style={styles.container}>
{datePicker && (
<RNDateTimePicker
value={datei}
mode={'date'}
// display={Platform.0S === 'ios' ? 'spinner' : 'default'}
is24Hour={true}
onChange={OnDateSelected}
style={styles.datePicker}
/>
)}
{timePicker && (
<RNDateTimePicker
value={time}
mode={'time'}
// display={Platform.0S === ‘ios' ? 'spinner' : ‘default'}
is24Hour={false}
onChange={onTimeSelected}
style={styles.datePicker}
/>
)}
{!datePicker && (
<View>
<TouchableOpacity
onPress={showDatePicker}
style={[styles.button, styles.buttonOutline]}
>
<Text style={styles.buttonOutlineText}>D A T E</Text>
</TouchableOpacity>
</View>
)}
{!timePicker && (
<View>
<TouchableOpacity
onPress={showTimePicker}
style={[styles.button, styles.buttonOutline]}
>
<Text style={styles.buttonOutlineText}>T I M E</Text>
</TouchableOpacity>
</View>
)}

Basically
function OnDateSelected(event,datei){
console.log(datei,"date")
setDatei(datei);
setDatePicker(false)
}
function onTimeSelected(event,time){
console.log(time,"time")
setTime(time);
setTimePicker(false)
}
The above functions had problem ,since first param was event and you were setting event as value, you need to set Date or time.
Its working now .
Check this example
https://snack.expo.dev/#gaurav1995/fascinated-donut
import RNDateTimePicker from '#react-native-community/datetimepicker';
import React,{ useState } from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
export default function App() {
const [datePicker,setDatePicker] = useState(false)
const [datei, setDatei] = useState(new Date())
const [timePicker,setTimePicker] = useState(false)
const [time,setTime] = useState(new Date(Date.now()))
function showDatePicker(){
setDatePicker(true)
}
function showTimePicker(){
setTimePicker(true)
}
function OnDateSelected(event,datei){
console.log(datei,"date")
setDatei(datei);
setDatePicker(false)
}
function onTimeSelected(event,time){
console.log(time,"time")
setTime(time);
setTimePicker(false)
}
return (
<View style={styles.container}>
{datePicker && (
<RNDateTimePicker
value={datei}
mode={'date'}
// display={Platform.0S === 'ios' ? 'spinner' : 'default'}
is24Hour={true}
onChange={OnDateSelected}
style={styles.datePicker}
/>
)}
{timePicker && (
<RNDateTimePicker
value={time}
mode={'time'}
// display={Platform.0S === ‘ios' ? 'spinner' : ‘default'}
is24Hour={false}
onChange={onTimeSelected}
style={styles.datePicker}
/>
)}
{!datePicker && (
<View>
<TouchableOpacity
onPress={showDatePicker}
style={[styles.button, styles.buttonOutline]}
>
<Text style={styles.buttonOutlineText}>D A T E</Text>
</TouchableOpacity>
</View>
)}
{!timePicker && (
<View>
<TouchableOpacity
onPress={showTimePicker}
style={[styles.button, styles.buttonOutline]}
>
<Text style={styles.buttonOutlineText}>T I M E</Text>
</TouchableOpacity>
</View>
)}
</View>
)
}
const styles = StyleSheet.create({
container:{
flex:1,
padding:40
}
})
Hope it helps. Feel free for doubts

#gaurav-roy
This is the following code that is what i am saying about,
and by inputting 1st sept 2022, 12:00 pm
the output shows 2022-09-16T06:06:05.570Z
console.log("Hello Admin")
var currentTime = datei
var currentOffset = currentTime.getTimezoneOffset();
var ISTOffset = 330; // IST
var ISTTime = new Date(currentTime.getTime() + (ISTOffset +
currentOffset)*60000);
var hoursIST = ISTTime.getHours()
var minutesIST = ISTTime.getMinutes()
console.log("datei",datei)
console.log("currentOffset", currentOffset)
console.log("ISTTime", ISTTime)
console.log("hoursIST", hoursIST)
console.log('minutesIST', minutesIST)

Related

How can I send ref to my custom TextInput component as a prop?

The custom TextInput component is illustrated below. I'm new to Typescript and have never tried to construct custom components like TextInput before; I intend to utilize this in all of my other components.
import React, { useState } from "react";
import { View, Text, TextInput, Pressable, KeyboardType } from "react-native";
import Ionicons from "react-native-vector-icons/Ionicons";
import { defaultStyle } from "./inputStyle";
interface Input {
label?: string;
placeholder?: string;
secured?: boolean;
inputStyle?: object;
iconName: string;
iconSize?: number;
keyboardType?: KeyboardType;
onTextChange?: (text: string) => void | undefined;
visibleLeftIcon?: boolean;
Error?: string;
selectionColor?: string;
}
export default function Input(input: Input) {
const [isSecured, setSecured] = useState<boolean>(true);
const [isFocused, setFocused] = useState<boolean>(false);
let _Error = input?.Error?.length !== undefined && input?.Error?.length !== 0;
return (
<View style={defaultStyle.container}>
<View>
<Text>{input.label}</Text>
</View>
<View
style={[
defaultStyle.wrapper,
isFocused && defaultStyle.info,
_Error && defaultStyle.warning,
]}
>
{input.visibleLeftIcon && (
<View style={defaultStyle.icon}>
<Ionicons
name={input.iconName}
size={input.iconSize ? input.iconSize : 22}
/>
</View>
)}
<TextInput
placeholder={input.placeholder}
onChangeText={(text) =>
input?.onTextChange && input?.onTextChange(text)
}
keyboardType={input.keyboardType}
secureTextEntry={input.secured && isSecured}
style={[defaultStyle.input, input.inputStyle]}
onBlur={() => setFocused(false)}
onFocus={() => setFocused(true)}
selectionColor={input.selectionColor}
/>
{input.secured && (
<Pressable
onPress={() => setSecured(!isSecured)}
style={defaultStyle.icon}
>
<Ionicons
name={isSecured ? "ios-eye-off-outline" : "ios-eye-outline"}
size={input.iconSize ? input.iconSize : 22}
/>
</Pressable>
)}
</View>
{_Error && (
<View>
<Text style={[defaultStyle.warning]}>{input?.Error}</Text>
</View>
)}
</View>
);
}
This is how I use it; I'm not sure how I'm going to pass a reference to my custom component. I tried searching but got no results.
import { ScrollView } from "react-native";
import Input from "../Component/Input";
export default function AuthLayout() {
return (
<ScrollView>
<Input
label="First Input"
secured={false}
keyboardType="decimal-pad"
onTextChange={(text) => console.log(text)}
iconName="ios-person-circle-outline"
visibleLeftIcon={true}
selectionColor="black"
/>
<Input
label="Second Input"
secured={true}
onTextChange={(text) => console.log(text)}
iconName="ios-person-circle-outline"
keyboardType="default"
placeholder="wambamram"
visibleLeftIcon={true}
selectionColor="red"
/>
</ScrollView>
);
}
I got the gist of the answer from this link stackoverflow.com/a/52417591, but it was still difficult for me to understand because I had never used a class component before, but I found the solution, and I hope this helps someone else.
What I did was add additional params that accepts a useRef() hook and a callback.
I named it:
onRef and onSubmitRef
import React, { useState, RefObject } from "react"; // new import RefObject
import { View, Text, TextInput, Pressable, KeyboardType } from "react-native";
import Ionicons from "react-native-vector-icons/Ionicons";
import { defaultStyle } from "./inputStyle";
interface Input {
label?: string;
placeholder?: string;
secured?: boolean;
inputStyle?: object;
iconName: string;
iconSize?: number;
keyboardType?: KeyboardType;
onTextChange?: (text: string) => void | undefined;
visibleLeftIcon?: boolean;
Error?: string;
selectionColor?: string;
onRef?: RefObject<TextInput> | null | undefined; // props that accepts ref hook
onSubmitRef?: () => void | undefined; // a callback that runs when TextInput submit
}
export default function Input(input: Input) {
const [isSecured, setSecured] = useState<boolean>(true);
const [isFocused, setFocused] = useState<boolean>(false);
let _Error = input?.Error?.length !== undefined && input?.Error?.length !== 0;
return (
<View style={defaultStyle.container}>
<View>
<Text>{input.label}</Text>
</View>
<View
style={[
defaultStyle.wrapper,
isFocused && defaultStyle.info,
_Error && defaultStyle.warning,
]}
>
{input.visibleLeftIcon && (
<View style={defaultStyle.icon}>
<Ionicons
name={input.iconName}
size={input.iconSize ? input.iconSize : 22}
/>
</View>
)}
<TextInput
placeholder={input.placeholder}
onChangeText={(text) =>
input?.onTextChange && input?.onTextChange(text)
}
keyboardType={input.keyboardType}
secureTextEntry={input.secured && isSecured}
style={[defaultStyle.input, input.inputStyle]}
onBlur={() => setFocused(false)}
onFocus={() => setFocused(true)}
selectionColor={input.selectionColor}
ref={input?.onRef} // add the props onRef
onSubmitEditing={() => input?.onSubmitRef && input?.onSubmitRef()} // a callback that runs when TextInput submit
/>
{input.secured && (
<Pressable
onPress={() => setSecured(!isSecured)}
style={defaultStyle.icon}
>
<Ionicons
name={isSecured ? "ios-eye-off-outline" : "ios-eye-outline"}
size={input.iconSize ? input.iconSize : 22}
/>
</Pressable>
)}
</View>
{_Error && (
<View>
<Text style={[defaultStyle.warning]}>{input?.Error}</Text>
</View>
)}
</View>
);
}
import React, { useRef, RefObject } from "react";
import { ScrollView, TextInput } from "react-native";
import Input from "../Component/Input";
export default function AuthLayout() {
let currentRefOne: RefObject<TextInput> | null | undefined = useRef(null);
let currentRefTwo: RefObject<TextInput> | null | undefined = useRef(null);
const HandleFocusOne = () => {
currentRefTwo?.current?.focus();
};
const HandleFocusTwo = () => {
currentRefOne?.current?.focus();
};
return (
<ScrollView>
<Input
label="First Input"
secured={false}
keyboardType="decimal-pad"
onTextChange={(text) => console.log(text)}
iconName="ios-person-circle-outline"
visibleLeftIcon={true}
selectionColor="black"
onRef={currentRefOne}
onSubmitRef={() => HandleFocusOne()}
/>
<Input
onRef={currentRefTwo}
onSubmitRef={() => HandleFocusTwo()}
label="Second Input"
secured={true}
onTextChange={(text) => console.log(text)}
iconName="ios-person-circle-outline"
keyboardType="default"
placeholder="wambamram"
visibleLeftIcon={true}
selectionColor="red"
/>
</ScrollView>
);
}

Stripe payment trigger All modals to open

When i put credits and make a payment the payment is succesfull but for some reason after the payment stripe is triggering all modals to open(from header), like it setting true all the modals , anyone know why ? ( The modal is from another compoenent name "Header" its working fine with everything else in my app .
Code below :
Merry Christmas :)
//React imports
import React, { useState } from 'react';
import { StyleSheet, View, Text, Pressable, Alert, Image , KeyboardAvoidingView , Dimensions , Platform} from 'react-native';
import { useNavigation , useFocusEffect } from '#react-navigation/native';
//Icon imports
import { AntDesign } from '#expo/vector-icons';
import { FontAwesome5 } from '#expo/vector-icons';
//API imports
import axios from 'axios';
import { StripeProvider, CardField, CardFieldInput, createToken, confirmPayment } from '#stripe/stripe-react-native';
import { Buffer } from "buffer";
//useConfirmPayment,useStripe
//My imports
import Header from './Header';
//.Env imports
import {URL} from '#env';
export default function Payment({route}) {
//Constructors for Card Details
const [card, setCard] = useState(CardFieldInput.Details | null);
//Use of navigate Hook
const navigation = useNavigation();
//My local variables
const bookItem = route.params.paramKey;
const bookID = bookItem.id;
const bookPrice = bookItem.Price;
const bookImage = bookItem.image;
//Payment function
const pay = async () => {
//First we create token for the payment
const resToken = await createToken({...card,type:'Card'})
//Then we create data for the payment , like amount and currency
const payData = {
amount : bookPrice * 100,
currency : "eur",
}
console.log(payData)
//If credit card fields are correct fil out ,then continue to further confirmations
if(Object.keys(resToken) == "token"){
//Request to check the success of the payment
await axios.post(URL+"/createPayment",
{...payData}).then((response)=>{
const { confirmPaymentIntent } = confirmPayment(response.data.paymentIntent,{paymentMethodType : 'Card'})
//If confirm is true then update the book table in Bought Column
if(Object.keys(response.data).length > 1){
Alert.alert("Success payment")
//Request to inform the table that this book is bought
axios.post( URL+"/bookBuy",
{
bookCheckID : bookID,
userBoughtItID : global.id
}).catch((error)=>{
console.log("Axios request failed to buy the book")
})
//End of second Axios request
}
else
{
console.log("Token Error ,maybe card credits is wrong")
Alert.alert("Error in payment,maybe card credits are wrong?")
}
}).catch((error)=>{
console.log("Axios request for payment failed")
})
//End of first Axios request
}
else{
Alert.alert("Card credentials are not Valid")
}
}
return (
//Stripe public key provider
<StripeProvider
publishableKey = "pk_test_51MAWjfI5vsjFWvGhrr5n2mAujexURegEgW4ujlSPpois9Em7FBzHrEkuv5zkeRjck8CeLBAcI761eVqgWQ3mL6EX00oSp0WeB6"
merchantIdentifier = "merchant.com.{{E-LIBRARY}}"
urlScheme = "your-url-scheme"
>
<KeyboardAvoidingView
style={{ height: Platform.OS ==='ios' ? Dimensions.get('window').height * 1 : Dimensions.get('window').height * 1}}
behavior={(Platform.OS === 'ios') ? 'position' : "position"}
enabled
keyboardVerticalOffset={Platform.select({ ios: -50, android: -50 })}
>
<View style = {styles.container}>
{/* Header */}
<Header />
{/* Container */}
<View style={styles.container}>
<View style = {styles.viewContainerForInfos}>
<Text style = {styles.bookText}>{bookItem.title}</Text>
<View style = {styles.imageView}>
<Image
style = {{width:'30%',height:'60%',borderRadius:22,position:'relative',resizeMode:'contain'}}
source = {{uri :'data:image/png;base64,' + Buffer.from(bookImage.data,'hex').toString('base64')}}
/>
<AntDesign name="checkcircleo" size={24} color="white" style = {{}} />
</View>
</View>
<View style = {styles.viewForCardinfo}>
<Text style = {styles.creditText}>Credit Card Informations</Text>
<FontAwesome5 name="id-card-alt" size={30} color="black" />
</View>
<View style = {{alignItems:'center',width:'100%',height:'100%'}}>
{/* Card component from Stripe */}
<CardField
postalCodeEnabled={true}
placeholder={{
number: '4242 4242 4242 4242',
}}
cardStyle={{
backgroundColor: '#FFFFFF',
textColor: '#000000',
borderWidth:2,
borderRadius:15
}}
style={{
width: '80%',
height: '8%',
marginVertical: '15%',
}}
onCardChange={(cardDetails) => {
setCard(cardDetails);
}}
/>
{/* Pressable in order for the client to pay */}
<Pressable style = {styles.pressable} onPress = {() => {pay()}}>
<Text style = {styles.pressableText}>Buy</Text>
</Pressable>
</View>
</View>
</View>
</KeyboardAvoidingView>
</StripeProvider>
)
}
Header
//React imports
import React, { useState } from 'react';
import { StyleSheet, Text, View, Pressable, Modal, Platform} from 'react-native';
import { useNavigation } from '#react-navigation/native';
//Icon Imports
import { SimpleLineIcons } from '#expo/vector-icons';
//Icons inside header modal
import { AntDesign } from '#expo/vector-icons';
import { Feather } from '#expo/vector-icons';
export default function Header() {
//Use of navigation Hook
const navigation = useNavigation();
//Modal Constructor
const [modalVisible,setModalVisible] = useState(false);
return (
<View style = {styles.Container}>
{/* Modal*/}
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
setModalVisible(!modalVisible);
}}>
<View style = {styles.modalStyle}>
{/* Pressable and Text for each functionality */}
<Pressable style = {styles.pressable} onPress = { () => navigation.navigate('Home')}>
<AntDesign name="home" size={24} color="black" style = {{marginRight:'2%',marginLeft:'2%'}}/>
<Text style = {styles. textInsideModalPressables}>Home</Text>
</Pressable>
<Pressable style = {styles.pressable} onPress = { () => navigation.navigate('MyBooks')}>
<Feather name="book" size={24} color="black" style = {{marginRight:'2%',marginLeft:'2%'}}/>
<Text style = {styles. textInsideModalPressables}>My Collection</Text>
</Pressable>
<Pressable style = {styles.pressable} onPress = { () => navigation.navigate('Profile')}>
<AntDesign name="profile" size={24} color="black" style = {{marginRight:'2%',marginLeft:'2%'}}/>
<Text style = {styles. textInsideModalPressables}>Profile</Text>
</Pressable>
<Pressable style = {styles.pressable} onPress = { () => navigation.navigate('Settings')}>
<Feather name="settings" size={24} color="black" style = {{marginRight:'2%',marginLeft:'2%'}}/>
<Text style = {styles. textInsideModalPressables}>Settings</Text>
</Pressable>
<Pressable style = {styles.pressable} onPress = { () => navigation.navigate('LogInPage')}>
<AntDesign name="logout" size={24} color="black" style = {{marginRight:'2%',marginLeft:'2%'}}/>
<Text style = {styles. textInsideModalPressables}>Log Out</Text>
</Pressable>
<Pressable onPress={ () => {setModalVisible(!modalVisible)}} style = {styles.pressable}>
<AntDesign name="closecircleo" size={24} color="black" style = {{marginRight:'2%',marginLeft:'2%'}}/>
<Text style = {styles. textInsideModalPressables}>Close modal</Text>
</Pressable>
</View>
</Modal>
{/* Pressable Mechanism in order to open the Modal */}
<Pressable onPress={ () => {setModalVisible(!modalVisible)}} style = {styles.pressableMenu}>
<SimpleLineIcons style = {styles.iconMenu} name="menu" size={24} color="white" />
<Text style = {styles.menuText}>Menu</Text>
</Pressable>
<View style ={{width:'50%',alignItems:'center',justifyContent:'center'}}>
<Text style = {styles.nameText}> E-Library</Text>
</View>
</View>
);}

component is not defined while opened on web

I have a component that work fine on android but it shows an error when I try to open it on the web using expo
Uncaught ReferenceError: TextInputMask is not defined
at ./src/components/atoms/TextInputMask.js (TextInputMask.js:6:1)
Here is TextInputMask code that gives an error
import React, { useEffect, useState } from "react";
import { View, StyleSheet } from "react-native";
import { TextInput, Text } from "react-native-paper";
import { TextInputMask as TextInputMaskDefault } from "react-native-masked-text";
export default TextInputMask = React.forwardRef(
(
{
label,
placeholder,
style,
mode = "outlined",
onChangeValue = () => {},
type = "custom",
options = {},
value,
icon,
disabled,
error,
...props
},
ref
) => {
const [data, setData] = useState();
const [maskValue, setMaskValue] = useState();
useEffect(() => {
if (value === null || value === undefined) {
setMaskValue("");
return;
}
if (value) {
value = String(value);
setMaskValue(value);
}
}, [value]);
useEffect(() => {
let rawValue = data?.getRawValue();
onChangeValue(rawValue, maskValue);
}, [maskValue]);
return (
<View style={style}>
<View style={styles.viewInput}>
<TextInput
style={styles.textInput}
label={label}
placeholder={placeholder}
mode={mode}
autoCapitalize="none"
autoCorrect={false}
autoCompleteType="off"
ref={ref}
disabled={disabled}
value={maskValue}
error={error}
render={(inputProps) => {
return (
<TextInputMaskDefault
{...inputProps}
type={type}
options={options}
onChangeText={(text) => setMaskValue(text)}
ref={(ref) => setData(ref)}
/>
);
}}
{...props}
/>
{icon ? (
<Text style={styles.textInputIcon}>
<TextInput.Icon
name={icon}
onPress={onPress}
size={30}
color={error ? Colors.red800 : null}
disabled={disabled}
/>
</Text>
) : null}
</View>
</View>
);
}
);
Any idea where the error might be? I wonder if there is a difference in creating component for android and web?

React Native Open Modal from another Modal

Hi I am new to React Native.
I want to open a modal from another modal.
I have a modal showing event details and user can delete this event. When they press delete button, I want to add another modal saying 'are you sure ?' as in the picture
[![enter image description here][1]][1]
My code doesn't work. I used onModalHide with setTimeOut to close the first one and opend the second one. But did not work. What can be the error here ?
import React, {useRef, useState} from 'react';
import {View, ScrollView, Text, Pressable} from 'react-native';
import styles from '#/screens/dashboard/events/CreatedEventDetails.styles';
import Modal from 'react-native-modal';
import common from '#/config/common';
import {useDispatch, useSelector} from 'react-redux';
import FastImage from 'react-native-fast-image';
import images from '#/config/images';
import {Icon, LoadingIndicator} from '#/components';
import {
closeEventDetailsModal,
fetchEventsList,
handleDeleteEvent,
handleWithDrawEvent,
LOADING,
} from '#/store/events/events';
import {EVENT_STATUS} from '#/constants/eventStatus';
import {strings} from '#/localization';
import moment from 'moment';
const CreatedEventDetails = ({isVisible, closeModal}) => {
const createdEventDetails = useSelector(state => state?.events?.eventDetails);
const userInfo = useSelector(state => state.profile.user);
const dispatch = useDispatch();
const currentEventId = useSelector(state => state.events.currentEventId);
const isLoading =
useSelector(state => state?.events?.eventResponseStatus) === LOADING;
const capitilizedLetter = createdEventDetails?.name
?.toLowerCase()
.charAt(0)
.toUpperCase();
const restOfTheName = createdEventDetails?.name?.slice(1);
const deleteEvent = id => {
dispatch(handleDeleteEvent(id));
dispatch(closeEventDetailsModal());
};
const withDrawEvent = id => {
dispatch(handleWithDrawEvent(id));
dispatch(closeEventDetailsModal());
};
function getBgColor(condition) {
switch (condition) {
case EVENT_STATUS.STATUS_NEW:
return '#ef9d50';
case EVENT_STATUS.STATUS_ACCEPTED:
return '#a1dc6a';
case EVENT_STATUS.STATUS_TENTATIVE:
return 'blue';
case EVENT_STATUS.STATUS_REJECTED:
return 'red';
default:
return '#ef9d50';
}
}
// to change the modal action according to created events or accepted events, we have to check
// if the logged in user id is matching with event owner id. ( delete - withdraw action )
const isOwner = createdEventDetails?.owner?.id === userInfo?.id;
const createdEventDate = createdEventDetails?.event_date;
const formattedDate = moment(createdEventDate).format('DD MMM, ddd');
const fromTime = createdEventDetails?.from_time?.toString();
const formattedFromTime = moment(fromTime, 'hh:mm').format('LT');
const toTime = createdEventDetails?.to_time?.toString();
const formattedToTime = moment(toTime, 'hh:mm').format('LT');
// second modal state
const [isDeleteModalVisible, setIsDeleteModalVisible] = useState(false);
// second modal function
const toggleModal = () => {
// when the second modal is open, I close the first one here.
dispatch(closeEventDetailsModal());
setIsDeleteModalVisible(!isDeleteModalVisible);
};
return (
<>
<View style={styles.modalContainer}>
<Modal
isVisible={isVisible}
propagateSwipe
onBackdropPress={() => this.setState(isVisible)}
onModalHide={() => {
setTimeout(() => {
setIsDeleteModalVisible(!isDeleteModalVisible);
}, 100);
}}
onModalWillHide={() => {
setTimeout(() => {
dispatch(fetchEventsList());
}, 500);
}}>
<View style={styles.content}>
{/* we have to check if event id is matching with currentEventId to prevent undefined problem
and also modal detail can have previous event detail. this will prevent the issue */}
{createdEventDetails.id !== currentEventId ? (
<LoadingIndicator visible />
) : (
<View>
<LoadingIndicator visible={isLoading} />
<View style={styles.closeBtnContainer}>
<Pressable style={styles.closeBtn} onPress={closeModal}>
<Text style={styles.closeText}>X</Text>
</Pressable>
</View>
<View>
<Text
style={
styles.contentTitle
}>{`${capitilizedLetter}${restOfTheName}`}</Text>
<Text style={styles.contenSubtTitle}>
{formattedDate}
{'\n'}
{formattedFromTime} - {formattedToTime}
</Text>
<Text style={styles.contentText}>
At {createdEventDetails?.location}
</Text>
<View style={styles.participantsContainer}>
<Text style={styles.contentTitle}>
{strings.eventDetails.participantsTitle} (
{createdEventDetails?.invites?.length})
</Text>
<View style={common.stickyButtonLine} />
<ScrollView>
{createdEventDetails?.invites?.map(invite => (
<View style={styles.checkboxContainer} key={invite.id}>
<View style={styles.imageContainer}>
{invite?.user?.thumb ? (
<FastImage
source={{uri: invite?.user?.thumb}}
style={styles.listItemUserImage}
resizeMode={FastImage.resizeMode.cover}
/>
) : (
<Icon
icon={images.ic_user}
style={styles.noUserIcon}
/>
)}
<Text style={styles.contentPersonName}>
{invite?.user?.name}
</Text>
</View>
<View
style={{
backgroundColor: getBgColor(invite?.status),
width: 25,
height: 25,
borderRadius: 25,
}}>
<Text>{''}</Text>
</View>
</View>
))}
</ScrollView>
</View>
<View>
<View>
<Text style={styles.contentTitle}>
{strings.eventDetails.hobbiesTitle} (
{createdEventDetails?.hobbies?.length})
</Text>
<View style={common.stickyButtonLine} />
<View style={styles.hobbiesContainer}>
{createdEventDetails?.hobbies?.map(hobby => (
<View style={styles.emojiContainer} key={hobby.id}>
<Text>{hobby.emoji}</Text>
</View>
))}
</View>
<View style={common.stickyButtonLine} />
</View>
<View style={[styles.buttons, styles.singleButtonAlign]}>
{isOwner ? (
<>
<Pressable
style={styles.decline}
onPress={toggleModal}
// onPress={() =>
// deleteEvent(createdEventDetails?.id)
// }
>
<Text style={styles.declineText}>
{strings.eventDetails.delete}
</Text>
</Pressable>
// second modal content here
{/* <Modal
isVisible={isDeleteModalVisible}
propagateSwipe>
<View style={styles.content}>
<Text>Hello!</Text>
<Pressable
title="Hide modal"
onPress={toggleModal}
/>
</View>
</Modal> */}
</>
) : (
<Pressable
style={styles.decline}
onPress={() =>
withDrawEvent(createdEventDetails?.id)
}>
<Text style={styles.declineText}>
{strings.eventDetails.withdraw}
</Text>
</Pressable>
)}
</View>
</View>
</View>
</View>
)}
</View>
</Modal>
</View>
// second modal content here
<View style={styles.modalContainer}>
<Modal isVisible={isDeleteModalVisible} propagateSwipe>
<View style={styles.content}>
<Text>Hello!</Text>
<Pressable title="Hide modal" onPress={toggleModal} />
</View>
</Modal>
</View>
</>
);
};;
export default CreatedEventDetails;
````
[1]: https://i.stack.imgur.com/BUMfa.png
Here are some way of debugging.
first check both the modal is showing up by passing harcoded true value for one by one.
if its working correctly, remove those timeouts and apicalls and
just check with useState only.
if all are fine then try to call
the api.

React native Flatlist navigate to diffrent page

import React from 'react';
import { FlatList, StyleSheet, Text, View , ScrollView ,TouchableHighlight,TouchableOpacity,Touchable} from 'react-native';
import { useState } from 'react';
function HomeContent({navigation}){
const [Level, setLevel] = useState([
{name:'ม.3\nปี59', key:1},
{name:'ม.3\nปี60', key:2},
{name:'ม.3\nปี61', key:3},
{name:'ม.3\nปี62', key:4},
{name:'ม.3\nปี63', key:5},
{name:'ม.6\nปี59', key:6},
{name:'ม.6\nปี60', key:7},
{name:'ม.6\nปี61', key:8},
{name:'ม.6\nปี62', key:9},
{name:'ม.6\nปี63', key:10},
])
const pressHandler = () => {
var i;
for (i = 1; i < 11; i++) {
navigation.navigate(`Exam${i}`) /*exam.{key_page}*/
}
}
return(
<View style = {styles.mainContent}>
<ScrollView showsVerticalScrollIndicator ={false}>
<FlatList
data = {Level}
renderItem = {({item}) => (
<TouchableOpacity onPress= {pressHandler}>
<View style = {styles.mainContentBox} >
<Text style={styles.mainContentBoxText}>{item.name}</Text>
</View>
</TouchableOpacity>
)}
numColumns = {2}
/>
</ScrollView>
</View>
)
}
I have many Exam pages (Exam[1-10]) how to navigate to a different page I try to use for loop the number but it doesn't work that make me go to all page 1-10
I am a newbie sorry if this is obvious
Try this way
const pressHandler = (item) => {
navigation.navigate(`Exam${item.key}`);
}
<TouchableOpacity onPress={() => { pressHandler(item)} >
<View style = {styles.mainContentBox} >
<Text style={styles.mainContentBoxText}>{item.name}</Text>
</View>
</TouchableOpacity>
get index prop from renderItem and navigate
renderItem = {({item,index}) => (
<TouchableOpacity onPress= {() => {
const pageNumber = index+1;
navigation.navigate(`Exam${pageNumber}`) /*exam.{key_page}*/
}}>
.....