React Native onpress not working - react-native

onRadioPressed does not seem to be called - what am I doing wrong? I also need to get the text contained in the 'clicked' item.
I believe I can get that with event.nativeEvent.text, correct?
Thanks for any help.
class RadioBtn extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
onRadioPressed(event) {
console.log('RADIOBUTTON PUSHED:');
}
render() {
return (
<View style={styles.radioGrp}>
<View style={styles.radioContainer}>
<TouchableHighlight onpress={() => this.onRadioPressed.bind(this)} underlayColor='#f1c40f'>
<Text style={styles.radio}>Left</Text>
</TouchableHighlight>
</View>
<View style={styles.radioContainer}>
<TouchableHighlight onpress={() => this.onRadioPressed.bind(this)} underlayColor='#f1c40f'>
<Text style={styles.radio}>Right</Text>
</TouchableHighlight>
</View>
</View>
);
}
}

So here:
<TouchableHighlight onpress={() => this.onRadioPressed.bind(this)} underlayColor='#f1c40f'>
<Text style={styles.radio}>Left</Text>
</TouchableHighlight>
First change onpress to onPress. Here () => this.onRadioPressed.bind(this) you are specifying an arrow function that returns another function this.onRadioPressed.bind(this) but you never trigger it.
Correct ways:
// You can do either this
<TouchableHighlight onPress={() => this.onRadioPressed()} underlayColor='#f1c40f'>
<Text style={styles.radio}>Left</Text>
</TouchableHighlight>
// Or you can do either this
<TouchableHighlight onPress={this.onRadioPressed.bind(this)} underlayColor='#f1c40f'>
<Text style={styles.radio}>Left</Text>
</TouchableHighlight>
I would recommend checking this article out https://medium.com/#housecor/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56#.irpdw9lh0

You can not bind the function inside onpress link this :
<TouchableHighlight onpress={() => this.onRadioPressed.bind(this)} underlayColor='#f1c40f'>
use it like this :
<TouchableHighlight onpress={() => this.onRadioPressed()} underlayColor='#f1c40f'>
if you want to bind the function then try this:
<TouchableHighlight onpress={this.onRadioPressed.bind(this)} underlayColor='#f1c40f'>
Cheers:)

Use below line
<TouchableHighlight onPress={this.onRadioPressed.bind(this)} underlayColor='#f1c40f'>
or using arrow function
<TouchableHighlight onPress={() => this.onRadioPressed()} underlayColor='#f1c40f'>

if https://stackoverflow.com/a/41651845/9264008 doesn't works check the way you have imported TouchableOpacity
✅ correct import import { TouchableOpacity } from 'react-native'
sometimes mistakenly weird import happens example below
❌ Import import { TouchableOpacity } from 'react-native-gesture-handler'

I'm using react-native 0.66 version and it's working fine.
import React, { useState } from 'react';
import { StyleSheet,Text,View } from "react-native";
const App = () => {
const [ prevCount, setCount ] = useState(1)
const onPress = () => setCount(prevCount => prevCount + 1);
return (
<View style={styles.container}>
<Text style={styles.prevCount}> {prevCount} </Text>
<Text style={styles.pressHere} onPress={onPress} > Press Here </Text>
</View>
)
};
const styles = StyleSheet.create({
container: {
marginTop: 50
},
pressHere:{
fontSize: 30
},
prevCount: {
fontSize: 20,
color: 'red'
}
})
export default App;
also, you can use this doc.

Related

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.

How to disable TouchableOpacity when pressed? React-Native

How can I disable TouchableOpacity when I click on it?
This is my code:
<TouchableOpacity onPress={() => this._pickupHandler(item.p, deliv.party, index)}>
<View style={styles.carg}>
<Text style={styles.delivered_text}>Ok{deliv.loca} {deliv.addres} {deliv.pos} </Text>
</View>
</TouchableOpacity>
just pass disabled prop to TouchableOpacity for your example
export default class Touchable extends Component {
constructor(props) {
super(props);
this.state = {
disabled: false,
};
}
onPressButton = (state) => {
this.setState({
disabled: state,
});
};
render() {
return (
<TouchableOpacity disabled={this.state.disabled} onPress={() => {
this.onPressButton(true);
this._pickupHandler(item.p, deliv.party, index)
}}>
<View style={styles.carg}>
<Text style={styles.delivered_text}>Ok{deliv.loca} {deliv.addres} {deliv.pos} </Text>
</View>
</TouchableOpacity>
);
}
}
Okay so you need another state which will refer to if you want to disable it.
lets make a state var TODISABLED and set it to false initially .
Now suppose you want to disable it after 1 click , you can do this by setting state to true after click :
<TouchableOpacity disabled={this.state.TODISABLED} onPress={() => {this._pickupHandler(item.p, deliv.party, index);this.setState({TODISABLED:true})}}>
<View style={styles.carg}>
<Text style={styles.delivered_text}>Ok{deliv.loca} {deliv.addres} {deliv.pos} </Text>
</View>
</TouchableOpacity>
Hope it helps. feel free for doubts

How to create a separate class for a component in react native and use it as a common class?

Hi I am learning react native. I am using Modal component of react native. I need to use the same across multiple times in app. Here the code
Now I am trying to call the function
{this.createModal(dataForMaritalStatus)}
instead of
/* <Modal visible={this.state.isModalVisible}
onRequestClose={() => {
this.setState({ isModalVisible: false })
}}
animationType="fade"
transparent={true}
>
<View style={styles.modalContainer}>
<ScrollView
showsVerticalScrollIndicator={true}
>
{dataForMaritalStatus === null ? <Text style={styles.nodata}>No data Found </Text> : dataForMaritalStatus.map((status, id) => (
<View key={id}>
<TouchableOpacity
style={styles.opacity}
onPress={() => {
this._toggleModal()
}}>
<Text style={styles.taskList}>{status.value}</Text>
</TouchableOpacity>
</View>
))}
</ScrollView>
</View>
</Modal>
*/
So how to make a common class for this component and pass different arrays of data and use it in render method ? The data is going to be different for different purposes and I need to maintain different states for different purposes.
Edit : I have written a method for it,but it calls the function but it does not render the modal, do I need to render it ?
createModal = (data) => {
<Modal visible={this.state.isModalVisible}
onRequestClose={() => {
this.setState({ isModalVisible: false })
}}
animationType="fade"
transparent={true}
>
<View style={styles.modalContainer}>
<ScrollView
showsVerticalScrollIndicator={true}
>
{data === null ? <Text style={styles.nodata}>No data Found </Text> : data.map((status, id) => (
<View key={id}>
<TouchableOpacity
style={styles.opacity}
onPress={() => {
this._toggleModal()
}}>
<Text style={styles.taskList}>{status.value}</Text>
</TouchableOpacity>
</View>
))}
</ScrollView>
</View>
</Modal>
}
Solution 1
Create a separate file customModalComponent.js, and pass in the array data through props. Change your Modal component a little bit, use this.props.dataForMaritalStatus for dataForMaritalStatus..
<ScrollView showsVerticalScrollIndicator={true}>
{this.props.dataForMaritalStatus === null ? <Text style={styles.nodata}>No data Found </Text>
: this.props.dataForMaritalStatus.map((status, id) => (
...
)}
</ScrollView>
and then on any other file, import CustomModal from './customModalComponent' and use it this way,
<CustomModal dataForMaritalStatus={yourArrayOfData}/>
Solution 2
If you are just using it in the same file, create a function instead
class myClass extends Component {
constructor(props) {
super(props);
this.createModal = this.createModal.bind(this);
}
render() {
...
}
createModal(dataForMaritalStatus) {
return (
//Insert your Modal code here
...
)
}
}
and use it this way in your render,
render() {
<View>
...
{
this.createModal(yourArrayOfData)
}
...
</View>
}
create new component in one folder.
app -> CommonModal.js
CommonModal.js
import React, { Component } from 'react';
import { View, Text, Modal, TouchableOpacity } from 'react-native';
export default class CommonModal extends Component{
constructor(props) {
super(props);
}
}
render(){
return(
<Modal visible={this.state.isModalVisible}
onRequestClose={() => {
this.setState({ isModalVisible: false })
}}
animationType="fade"
transparent={true}
>
<View style={styles.modalContainer}>
<ScrollView
showsVerticalScrollIndicator={true}
>
{this.props.dataForMaritalStatus === null ? <Text style={styles.nodata}>No data Found </Text> : this.props.dataForMaritalStatus.map((status, id) => (
<View key={id}>
<TouchableOpacity
style={styles.opacity}
onPress={() => {
this._toggleModal()
}}>
<Text style={styles.taskList}>{status.value}</Text>
</TouchableOpacity>
</View>
))}
</ScrollView>
</View>
</Modal>
)
}
note: i have used this.props.dataForMaritalStatus
And then use it wherever you need the component
app -> Second.js
Second.js
import React, { Component } from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import CommonModal from './CommonModal';
export default class Second extends Component{
constructor(props){
super(props);
this.state={
dataForMaritalStatus:['val1','val2']
}
}
render(){
return(<View style={{flex:1}}>
<CommonModal dataForMaritalStatus={this.state.dataForMaritalStatus}/>
</View>)}
}
Create a separate component for Model
import React, { Component } from "react";
import { Text, View, Modal, ScrollView, TouchableOpacity, Text } from "react-native";
export default class CustomModel extends Component {
render() {
const { dataForMaritalStatus } = this.props;
return (
<Modal
visible={this.state.isModalVisible}
onRequestClose={() => {
this.setState({ isModalVisible: false });
}}
animationType="fade"
transparent={true}
>
<View style={styles.modalContainer}>
<ScrollView showsVerticalScrollIndicator={true}>
{dataForMaritalStatus === null ? (
<Text style={styles.nodata}>No data Found </Text>
) : (
dataForMaritalStatus.map((status, id) => (
<View key={id}>
<TouchableOpacity
style={styles.opacity}
onPress={() => {
this._toggleModal();
}}
>
<Text style={styles.taskList}>{status.value}</Text>
</TouchableOpacity>
</View>
))
)}
</ScrollView>
</View>
</Modal>
);
}
}
don't forget to export that component.
Now import that component in the file where you want to use that
import Model from "./CustomModel";
and use it this way
<CustomModel dataForMaritalStatus=[] />
you can pass data using props like a do above.
you can learn more about props here: https://facebook.github.io/react-native/docs/props

React Native - Is not a function - Is Undefined

I have the following code in React Native
import React from "react";
import {
StyleSheet,
Text,
View,
Button,
TextInput,
Image,
ScrollView
} from "react-native";
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
apiData: [],
};
this.getButton();
}
deleteButton(Id){
fetch("http://192.168.2.22:9090/usuario/" + (Id), {
method: "DELETE"
})
.then(responseData => {
console.log(responseData.rows);
})
.done();
this.dataId = null;
}
render() {
const data = this.state.apiData;
let dataDisplay = data.map(function(jsonData) {
return (
<View style={styles.lista} key={jsonData.id}>
<View style={styles.bordeLista}>
<View style={styles.fila}>
<View style={styles.contenedorfoto}>
<Image
style={styles.foto}
source={require("./img/login.png")}
/>
</View>
<View style={styles.datos}>
<Text>Nombre: {jsonData.nombre}</Text>
<Text>E-mail: {jsonData.email}</Text>
<Text>Telefono: {jsonData.telefono}</Text>
</View>
</View>
<View style={styles.fila}>
<View style={styles.contenedorboton}>
<View style={styles.botoniz}>
<Button title="Modificar" onPress={() => {}} />
</View>
<View style={styles.botonde}>
<Button
title="Eliminar"
onPress={() => this.deleteButton(jsonData.Id)}
color="#ee4c4c"
/>
</View>
</View>
</View>
</View>
</View>
);
});
return (
<Text style={styles.titulo}>Usuarios desde BD MySQL</Text>
<ScrollView>
<View>{dataDisplay}</View>
</ScrollView>
</View>
);
}
}
And I want to call deleteButton() from this button
<Button
title="Eliminar"
onPress={() => this.deleteButton(jsonData.Id)}
color="#ee4c4c"
/>
But I get the following error, That the method is not a function and that it is not defined.
Error
How could I use the function? And I'm setting the parameter well (id). Thank you.
PS: I have deleted parts of the code and only left the most important, if you need the full code I can provide it
You're losing the reference to this because you're using an old-style lambda.
Replace this
data.map(function(jsonData) {
with an arrow function, like this
data.map(jsonData => {

React Native : Modal closing functionality

I am currently following the modal example given here.
https://facebook.github.io/react-native/docs/modal.html
The code works and it is indeed showing a modal box.
But there is no "close" functionality except the one via TouchableHighlight onPress event.
Is it possible to have a "close modal" functionality via "X" on the corner ?
I checked out the props and I am not able to find any.
So does this mean that using only the TouchableHighlight's onPress event alone you will be able to control the modal's closing ?
App.js code
import React, { Component } from 'react';
import { Modal, Text, TouchableHighlight, View } from 'react-native';
export default class ModalExample extends Component {
state = {
modalVisible: false,
}
setModalVisible(visible) {
this.setState({modalVisible: visible});
}
render() {
return (
<View style={{marginTop: 22}}>
<Modal
animationType="slide"
transparent={false}
visible={this.state.modalVisible}
onRequestClose={() => {alert("Modal has been closed.")}}
>
<View style={{marginTop: 22}}>
<View>
<Text>Hello World!</Text>
<TouchableHighlight onPress={() => {
this.setModalVisible(!this.state.modalVisible)
}}>
<Text>Hide Modal</Text>
</TouchableHighlight>
</View>
</View>
</Modal>
<TouchableHighlight onPress={() => {
this.setModalVisible(true)
}}>
<Text>Show Modal</Text>
</TouchableHighlight>
</View>
);
}
}
import React, { Component } from 'react';
import { Modal, Text, TouchableHighlight, View } from 'react-native';
export default class ModalExample extends Component {
state = {
modalVisible: false,
}
setModalVisible(visible) {
this.setState({modalVisible: visible});
}
closeModal = () => {
this.setState({modalVisible: false})
}
render() {
return (
<View style={{marginTop: 22}}>
<Modal
animationType="slide"
transparent={false}
visible={this.state.modalVisible}
onRequestClose={() => {alert("Modal has been closed.")}}
>
<View style={{marginTop: 22}}>
<View>
<Text>Hello World!</Text>
<TouchableHighlight onPress={() => {
this.setModalVisible(!this.state.modalVisible)
}}>
<Text>Hide Modal</Text>
</TouchableHighlight>
</View>
<CloseButton onPress={this.closeModal} /> // Create your 'X' button with your preferred styling
</View>
</Modal>
<TouchableHighlight onPress={() => {
this.setModalVisible(true)
}}>
<Text>Show Modal</Text>
</TouchableHighlight>
</View>
);
}
}
You just need to add a button to the modal with your preferred styling and on the button's onPress listener set the state variable modalVisible to false for hiding the modal.