OnPress not getting called - react-native

I'm trying to build an application using React Native.
I made a custom button, and the onPress is not working, tried to look for answers but couldn't find any, The code looks just like the docs (copied from there).
This is the custom button:
import React from 'react';
import { View, Text, StyleSheet, TouchableHighlight, TouchableOpacity } from 'react-native';
import COLORS from '../constants/constants';
class AppButton extends React.Component {
render() {
return(
<View style={styles.container}>
<TouchableOpacity>
<Text style={styles.title}>
{this.props.title}
</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: COLORS.appOrange,
borderRadius: 20,
elevation: 3,
flexShrink: 0,
width: '100%',
height: 60,
justifyContent: 'center'
},
title: {
fontSize: 24,
color: COLORS.appWhite,
textAlign: 'center',
},
});
export default AppButton;
This is how I try to use the onPress:
import React from 'react';
import { View, Text, StyleSheet, TextInput } from 'react-native';
import COLORS from '../constants/constants';
import Card from '../components/card';
import { Colors } from 'react-native/Libraries/NewAppScreen';
import AppTextInput from '../components/appTextInput';
import AppButton from '../components/appButton';
class Login extends React.Component {
onPress = () => {
console.log("hello world!##!###!#");
// this.setState({
// count: this.state.count + 1
// });
};
render() {
return(
<View style={styles.superContainer}>
<View style={styles.formContainer}>
<AppTextInput placeHolderText="Email#Address.com"></AppTextInput>
<AppTextInput placeHolderText="Passwrod"></AppTextInput>
</View>
<View style={styles.buttonContainer}>
<AppButton
title="LOGIN"
style={styles.loginButton}
onPress={this.onPress}
/>
</View>
</View>
);
}
}
I tried to look at the console, but nothing gets printed out, tried few different examples I saw on the internet but the tap just won't register.

I have passed OnPress method as props to AppButton and attached this method to TouchableOpcaity OnPress Event
import React from 'react';
import { View, Text, StyleSheet, TouchableHighlight, TouchableOpacity } from 'react-native';
import COLORS from '../constants/constants';
class AppButton extends React.Component {
render() {
return(
<View style={styles.container}>
<TouchableOpacity onPress={this.props.handleOnPress}>
<Text style={styles.title}>
{this.props.title}
</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: COLORS.appOrange,
borderRadius: 20,
elevation: 3,
flexShrink: 0,
width: '100%',
height: 60,
justifyContent: 'center'
},
title: {
fontSize: 24,
color: COLORS.appWhite,
textAlign: 'center',
},
});
export default AppButton;
import React from 'react';
import { View, Text, StyleSheet, TextInput } from 'react-native';
import COLORS from '../constants/constants';
import Card from '../components/card';
import { Colors } from 'react-native/Libraries/NewAppScreen';
import AppTextInput from '../components/appTextInput';
import AppButton from '../components/appButton';
class Login extends React.Component {
onPress = () => {
console.log("hello world!##!###!#");
// this.setState({
// count: this.state.count + 1
// });
};
render() {
return(
<View style={styles.superContainer}>
<View style={styles.formContainer}>
<AppTextInput placeHolderText="Email#Address.com"></AppTextInput>
<AppTextInput placeHolderText="Passwrod"></AppTextInput>
</View>
<View style={styles.buttonContainer}>
<AppButton
title="LOGIN"
style={styles.loginButton}
handleOnPress={this.onPress}
/>
</View>
</View>
);
}
}

In your case you didn't pass the onPress props into TouchableOpacity inside your custom button component.
Try this
Custom Button
import React from "react";
import {
View,
Text,
StyleSheet,
TouchableHighlight,
TouchableOpacity
} from "react-native";
import COLORS from "../constants/constants";
class AppButton extends React.Component {
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.props.onPress}>
<Text style={styles.title}>{this.props.title}</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: COLORS.appOrange,
borderRadius: 20,
elevation: 3,
flexShrink: 0,
width: "100%",
height: 60,
justifyContent: "center"
},
title: {
fontSize: 24,
color: COLORS.appWhite,
textAlign: "center"
}
});
export default AppButton;
Login Class
import React from "react";
import { View, Text, StyleSheet, TextInput } from "react-native";
import COLORS from "../constants/constants";
import Card from "../components/card";
import { Colors } from "react-native/Libraries/NewAppScreen";
import AppTextInput from "../components/appTextInput";
import AppButton from "../components/appButton";
class Login extends React.Component {
onPress = () => {
console.log("hello world!##!###!#");
// this.setState({
// count: this.state.count + 1
// });
};
render() {
return (
<View style={styles.superContainer}>
<View style={styles.formContainer}>
<AppTextInput placeHolderText="Email#Address.com"></AppTextInput>
<AppTextInput placeHolderText="Passwrod"></AppTextInput>
</View>
<View style={styles.buttonContainer}>
<AppButton
title="LOGIN"
style={styles.loginButton}
onPress={this.onPress}
/>
</View>
</View>
);
}
}

Are you sure the "this" verb refer to the right object (class instance) ?
Let's check this :
class Login extends React.Component {
const onPress = () => {
console.log("the world is not enough");
};
render() {
/* assign this class instance to that reference */
const that = this;
return(
...
<View style={styles.buttonContainer}>
<AppButton
title="LOGIN"
style={styles.loginButton}
/* use that class reference */
onPress={that.onPress}
/>
</View>
...
);
}
}

Related

Pass state value as props react native

I am trying to make a reusable text input component, but I want to grab the value that the user types to manipulate it on the App.js
TextInputComponent.js
import React, {useState} from 'react';
import { StyleSheet, View, TextInput } from 'react-native'
const TextInputComponent = (props) => {
const [text, onChangeText] = useState("")
return (
<View>
<TextInput style={styles.container} value={text} onChangeText={onChangeText} placeholder="Enter"/>
</View>
)
}
const styles = StyleSheet.create({
container: {
height: 50,
width: 200,
padding: 10,
margin: 10,
borderWidth: 1,
borderColor: "black",
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default TextInputComponent
App.js
import { StatusBar } from 'expo-status-bar';
import React, {useState} from 'react';
import { Button, StyleSheet, Text, TextInput, View } from 'react-native';
import TextInputComponent from './src/components/TextInputComponent';
export default function App() {
return (
<View style={styles.container}>
<View style={{flexDirection: 'row' }}>
<Text>Test</Text>
<TextInputComponent/>
<Button title="A" onPress={()=> console.log(-------> text value from TextInputComponent <-----)}></Button>
</View>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
In order to access the state value created on the TextInputComponent.js what do I need to do?
One thing you can do is to pass a custom method through to the component and then use it as the onChangeText method:
const TextInputComponent = ({ customMethod }) => {
const [text, onChangeText] = useState("")
return (
<View>
<TextInput style={styles.container} value={text} onChangeText={(txt) => customMethod(txt)} placeholder="Enter"/>
</View>
)
}
Then in App.js you have the method:
customMethod = (txt) => {
// do something with txt variable
}
and:
<TextInputComponent customMethod={customMethod} />
Might require some tweaking to get it to work (I didn't test it), but that's the general idea.

React native Button not working when i tap it on my mobile using expo application

I am having a problem with my button. i have just started learning reactnative.
import { StatusBar } from 'expo-status-bar';
import React,{ useState } from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
export default function App() {
const [name, setName] = useState('Hamza');
const clickHandler= () => {
setName('Awais');
};
return (
<View style={styles.container}>
<Text >My Name is { name }</Text>
<Text></Text>
<View style={styles.buttonContainer}>
<Button title='update State' onPress={ clickHandler }/>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
buttonContainer:{
marginTop:20,
},
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Try this way
<Button title='update State' onPress={() => clickHandler() } />

Import/Export Components

I'm trying to build a custom input component, and render it on another page
Here is my code
import React from "react";
import { View, TextInput, StyleSheet, Text } from "react-native";
import {
widthPercentageToDP as wp,
heightPercentageToDP as hp,
} from "react-native-responsive-screen";
import { MaterialCommunityIcons } from "#expo/vector-icons";
class RegisterTextBox extends React.Component {
render() {
const RegisterTextInput = ({
value,
placeholder,
onChangeText,
onBlur,
secureTextEntry,
inputStyle,
viewStyle,
eyeIcon = false,
}) => {
return (
<View style={[styles.container, viewStyle]}>
<TextInput
style={[styles.main, inputStyle]}
value={value}
onChangeText={onChangeText}
onBlur={onBlur}
placeholder={placeholder}
secureTextEntry={secureTextEntry}
/>
{eyeIcon ? (
<MaterialCommunityIcons
name="eye-off"
size={24}
color="black"
style={{ paddingTop: 5 }}
/>
) : (
<View />
)}
</View>
);
};
const styles = StyleSheet.create({
container: {
height: hp(5.4),
width: wp(65.2),
borderBottomColor: "grey",
borderBottomWidth: 1,
flexDirection: "row",
justifyContent: "space-between",
},
main: {},
});
}
}
export default RegisterTextBox;
I want const RegisterTextInput to be rendered and use dynamic data, but I seem to get an error when trying to use it "Error: RegisterTextBox(...): Nothing was returned from render.
this is how I'm trying to use it:
...
import RegisterTextInput from "../components/registerInput";
<View style={styles.emailInputsContainer}>
<RegisterTextInput
style={styles.emailInput}
placeholder="Email"
value={"email"}
onChangeText={}
/>
</View>
...
Where Is my problem?
Note: I want to use states on this component
Try with this...
import React from "react";
import { View, TextInput, StyleSheet, Text } from "react-native";
import {
widthPercentageToDP as wp,
heightPercentageToDP as hp,
} from "react-native-responsive-screen";
import { MaterialCommunityIcons } from "#expo/vector-icons";
class RegisterTextBox extends React.Component {
constructor(props) {
super(props);
}
render() {
const {
value,
placeholder,
onChangeText,
onBlur,
secureTextEntry,
inputStyle,
viewStyle,
eyeIcon = false,
} = this.props;
return (
<View style={[styles.container, viewStyle]}>
<TextInput
style={[styles.main, inputStyle]}
value={value}
onChangeText={onChangeText}
onBlur={onBlur}
placeholder={placeholder}
secureTextEntry={secureTextEntry}
/>
{eyeIcon ? (
<MaterialCommunityIcons
name="eye-off"
size={24}
color="black"
style={{ paddingTop: 5 }}
/>
) : (
<View />
)}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
height: hp(5.4),
width: wp(65.2),
borderBottomColor: "grey",
borderBottomWidth: 1,
flexDirection: "row",
justifyContent: "space-between",
},
main: {},
});
export default RegisterTextBox;

undefined is not a function(evaluating........... in react native when clicking on onPress

Here is the code, I'm not able to invoke removeItem function while clicking on Icon tag.Please help me out I'm a beginner in react native.I'm stuck for 3 days.
Please help me out in proper way of calling function.Thanks in advanced
import React from 'react';
import { StyleSheet, Text, View,TextInput,KeyboardAvoidingView,Dimensions,ScrollView,Alert,TouchableOpacity,Button,TouchableHighlight } from 'react-native';
import Icon from 'react-native-vector-icons/Entypo';
var {height, width} = Dimensions.get('window');
var d = new Date();
export default class App extends React.Component {
constructor(props){
super(props);
this.state = {
noteList: [],
noteText: ''
}
}
addItems(){
var a = this.state.noteText;
this.state.noteList.push(a)
this.setState({
noteText:''
})
console.log(this.state.noteList)
}
removeItem(key) {
console.log('removeItem is working',key);
}
render() {
return (
<KeyboardAvoidingView style={styles.container} behavior="padding" enabled>
<View style={styles.header}>
<Text style={{fontSize: 20}}>NOTE APPLICATION</Text>
</View>
<View style={styles.body}>
<ScrollView>
{this.state.noteList.map(function(value,key){
return(
<View key={key} style={styles.bodyElements} >
<Text>{key}</Text>
<Text>{value}</Text>
<Text>{d.toDateString()}</Text>
<Icon onPress={(key) => this.removeItem(key)} name="cross" color="white" size={40}/>
</View>
)
})}
</ScrollView>
</View>
<View style={styles.footer}>
<TextInput style={{marginTop:10,marginLeft:10}}
placeholder="Jot down your thoughts before they vanish :)"
width={width/1.2}
underlineColorAndroid="transparent"
onChangeText={(noteText) => this.setState({noteText})}
value={this.state.noteText}
/>
<Icon style={{marginTop:15}} name="add-to-list" color="white" size={40} onPress={this.addItems.bind(this)}/>
</View>
</KeyboardAvoidingView>
);
}
}
I do not have your array data so i use a,b values. but mamy issue with map functionis here, you need to pass this as params . check in the code
import React from 'react';
import { StyleSheet, Text, View, TextInput, KeyboardAvoidingView, Dimensions, ScrollView, Alert, TouchableOpacity, Button, TouchableHighlight } from 'react-native';
// import Icon from 'react-native-vector-icons/Entypo';
var { height, width } = Dimensions.get('window');
var d = new Date();
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
noteList: ['a','b'],
noteText: ''
}
}
addItems() {
var a = this.state.noteText;
this.state.noteList.push(a)
this.setState({
noteText: ''
})
console.log(this.state.noteList)
}
removeItem(key) {
console.warn('removeItem is working');
}
render() {
return (
<View >
<View style={styles.header}>
<Text style={{ fontSize: 20 }}>NOTE APPLICATION</Text>
<Button title="try" onPress={(key) => this.removeItem()} name="cross"
size={40} />
</View>
<View style={styles.body}>
{this.state.noteList.map(function(value,key){
return(
<View key={key} style={styles.bodyElements} >
<Text>{key}</Text>
<Text>{value}</Text>
<Text>{d.toDateString()}</Text>
<Button title="try"
onPress={() => this.removeItem()}
name="cross"
color="white"
size={40}/>
</View>
)
},this)}
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 25,
textAlign: 'center',
margin: 10,
},
child: {
fontSize: 18,
textAlign: 'center',
margin: 10,
backgroundColor: 'green',
height: 100,
width: 200,
},
});

Can't go to the next page after login- react native stack navigation

i have three pages.
app.js, login.js and mainpage.js
i am having problem of going from login to mainpage.
The problem appears to be in Login.js in logibtn function.
i also tried this.props.navigation instead of passing a parameter, but it still didnt work.
App.js
import React, {Component} from 'react';
import {View, StyleSheet, TextInput, Text, TouchableOpacity } from 'react-native';
import { StackNavigator} from "react-navigation";
import Login from './src/Login';
import MainPage from './src/MainPage';
const NavigationApp = StackNavigator({
LoginPage:{
screen: Login
},
MainPagePage:{
screen: MainPage
}
}
)
export default class extends Component{
render(){
return(
<NavigationApp/>
)
}
}
Login.js
import React, {Component} from 'react';
import {View, StyleSheet, TextInput, Text, TouchableOpacity } from 'react-native';
export default class extends Component{
static navigationOptions={
title:"Login"
};
constructor(props){
super(props);
this.state= {title:'login', username:'', password:''}
this.loginbtn = this.loginbtn.bind(this);
}
loginbtn(navigate){
let username='Parisa';
let password='123';
if(this.state.username===username && this.state.password===password){
navigate('MainPage')
title="MainPage";
}
else{
alert("Incorrect Username or Password");
}
}
render(){
const { navigate } = this.props.navigation;
return(
<View style={Styles.container}>
<Text style={Styles.title}>
To-Do List
</Text>
<View style={Styles.shadow}>
<TextInput
style={Styles.input}
placeholder="Enter username"
onChangeText={(text) => {this.state.username = text} }
/>
<TextInput
style={Styles.input}
secureTextEntry={true}
placeholder="Enter password"
onChangeText={(text) => {this.state.password = text} }
/>
<TouchableOpacity style={Styles.button} onPress={() => this.loginbtn(navigate)}>
<Text style={Styles.buttonText}>Log in</Text>
</TouchableOpacity>
</View>
</View>
)
}
}
const Styles = StyleSheet.create({
container:{
flex: 1,
backgroundColor: "white",
justifyContent: 'center',
alignItems: 'center',
padding: 10,
},
title:{
fontWeight:"bold",
fontSize: 30,
width:180,
textAlign: "center",
color:"#310505"
},
shadow:{
elevation: 50,
borderRadius: 4,
borderWidth: 20,
borderColor: '#Fff',
backgroundColor: '#FFF'
},
input:{
color:"#310505"
},
button:{
backgroundColor:'#310505',
width:180,
height: 30
},
buttonText:{
fontSize: 20,
color:"white",
textAlign: "center"
}
}
)
MainPage.js
import React, {Component} from "react";
import {View, Text} from "react-native";
export default class extends Component{
static navigationOptions ={
title:"MainPage"
}
render(){
return(
<View>
<Text>MainPage</Text>
</View>
)
}
}
Use
this.props.navigation.navigate('MainPagePage')
instead of
this.props.navigation.navigate('MainPage')
as you have defined inside the Stack navigator.