Reputation: 185
By using react native and php, I'm trying to build a login page, fetching data from mysql server, if its in, the screen will be redirected to another screen. I'm totally new in react, and I'm lost at setState, which run the login function every time I update the textinput. So everytime I type, the alert will appear until I finally managed to insert correct data into the fields. I only want the function to run once the button is clicked. How do I solve this? Thanks.
Shown below is the code.
import React, { useState } from 'react';
import { ImageBackground, View, StyleSheet, Image, Text, TextInput, TouchableOpacity, Alert, Button } from 'react-native';
export default function LoginScreen({navigation}) {
const [employeeNo, setEmployeeNo] = useState('');
const [employeePassword, setEmployeePassword] = useState('');
const loginEmployee = () => {
var empNo = employeeNo;
var empPass = employeePassword;
if(empNo.length==0 || empPass==0){
alert("Please insert all required fields!")
}else{
var apiURL = "http://example.com/api/login.php";
var headers = {
'Accept':'application/json',
'Content-Type':'application.json',
};
var data = {
empNo: empNo,
empPass: empPass
};
fetch(apiURL,
{
method:'POST',
headers: headers,
body: JSON.stringify(data)
})
.then((response)=>response.json())
.then((response)=>
{
if (response[0].isCorrect ==1){
navigation.navigate('Home');
}else{
Alert.alert(
"Error","Invalid employeeNo / Password. Please try again!"
)
}
}
)
.catch((error)=>{
alert("Error" + error);
})
}
}
return(
<View style={styles.container}>
<ImageBackground
source={require('../assets/log-bg.jpg')}
style={styles.image}>
<Image
source={require('../assets/logo.png')}
style={styles.logo}
/>
<Text style={styles.text}>Mobile Application</Text>
<View style={styles.inputStack}>
<Text
style={styles.loginText}
>Please Sign in to Continue</Text>
<TextInput
style={styles.input}
placeholder="Employee No..."
keyboardType='numeric'
onChangeText={employeeNo=>setEmployeeNo(employeeNo)}
/>
<TextInput
style={styles.input}
placeholder="Password..."
secureTextEntry={true}
onChangeText={employeePassword=>setEmployeePassword(employeePassword)}
/>
<Text
style={styles.hyperlink}
>Doesn't have an account? Click here to register.</Text>
<Button title='Press' onPress={()=> navigation.navigate('Home')}/>
</View>
<View style={ styles.bottomView} >
<TouchableOpacity
onPress={loginEmployee()}
style={styles.button}>
<Text style={styles.textStyle}
>LOGIN</Text>
</TouchableOpacity>
</View>
</ImageBackground>
</View>
)
}
Upvotes: 0
Views: 1263
Reputation: 1042
onPress={loginEmployee()}
This line is the problem, basically everytime the component update it will trigger your function.
Why ?
For exampel: you do with a .map() to display some content dynamically, you use {this.state.data.map((item) => <span>{item.name}</span>)}
In your view page you agree with me that you will see the names displaying right ?
Beceause you're executing this function, react reads it and execute it like you've asked.
Now concerning your button, you don't want to be executed all the time, just when it is press. To fix that you need to write like this:
onPress={() => loginEmployee()}
Or like joessel wrote it works fine too
onPress={loginEmployee}
Doing so, it won't trigger automatically, but only when the event is launched
Upvotes: 1
Reputation: 1443
The issue is here:
<TouchableOpacity
onPress={loginEmployee()} <--- Here
style={styles.button}
>
<Text style={styles.textStyle}>LOGIN</Text>
</TouchableOpacity>
You are calling loginEmployee at each re-render, what you want is to reference your function to be called only when the use click on the button:
<TouchableOpacity
onPress={loginEmployee} <--- Just remove the paranthesis
style={styles.button}
>
<Text style={styles.textStyle}>LOGIN</Text>
</TouchableOpacity>
Upvotes: 1