I am currently working on building app with react native.
when i click button, why doesnt it update my user right away?
here is the code:
useEffect(() => {
const getUser = async (email) => {
try {
console.log("get user initated, email: ", email)
const response = await fetch(
`http://192.168.1.128:3005/api/v1/finduser/${email}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
}
);
console.log("response: ", response['status'])
if (!response.ok) {
cconsole.error(
`This is an HTTP error: The status is ${response.status}, user not found: ${email}`
);
}
let data = await response.json();
setError(null);
if (data) {
console.log("type of data: ", typeof(JSON.stringify(data)))
console.log("data: ", data[0].email)
// setUser({ email: email })
// console.log("user email: ", user[0].email)
setUser(data)
setUserFound(true);
}
console.log("user: ",user)
console.log("data: ", data)
console.log("userfound: ", userFound)
if (!userFound) {
navigation.navigate('Signup');
}
} catch(err) {
setError(err.message);
console.log("error message: ", err.message)
setUser(null);
} finally {
setLoading(false);
}
}
getUser();
}, [user])
const handleLogin = async () => {
setEmailError('')
if ('' === email) {
setEmailError('Please enter your email')
}
try {
await getUser(email);
}
catch(err) {
setError(err.message);
}
}
const handleLoginPress = () => {
return () => {
handleLogin(email);
};
};
return (
<View className={'mainContainer'} style={styles.container}>
<View className={'titleContainer'}>
<Text>
Please Log In
{"n"}
Connect with Google
</Text>
</View>
<Text>
{"n"}
</Text>
<View className={'inputContainer'}>
<TextInput
value={email}
placeholder="Enter your email here"
onChangeText={(val) => setEmail(val)}
className={'inputBox'}
/>
<Text className="errorLabel">{emailError}</Text>
</View>
<Text>
{"n"}
</Text>
<View className={'inputContainer'}>
<Button title={'Log in'} onPress={handleLoginPress()} />
</View>
<Text>{email}</Text>
</View>
)
};
i also tried separating the useEffect and getUser(),
const getUser = async (email) => {
try {
console.log("get user initated, email: ", email)
const response = await fetch(
`http://192.168.1.128:3005/api/v1/finduser/${email}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
}
);
console.log("response: ", response['status'])
if (!response.ok) {
cconsole.error(
`This is an HTTP error: The status is ${response.status}, user not found: ${email}`
);
}
let data = await response.json();
setError(null);
if (data) {
console.log("type of data: ", typeof(JSON.stringify(data)))
console.log("data: ", data[0].email)
// setUser({ email: email })
// console.log("user email: ", user[0].email)
setUser(data)
setUserFound(true);
}
console.log("user: ",user)
console.log("data: ", data)
console.log("userfound: ", userFound)
if (!userFound) {
navigation.navigate('Signup');
}
} catch(err) {
setError(err.message);
console.log("error message: ", err.message)
setUser(null);
} finally {
setLoading(false);
}
}
useEffect(() => {
getUser();
}, [user])
with and without user in bracket (also email). however, it does not update my user until i click it 2-3 times.
I think i tired every solutions on google, but most examples are about updating the numbers after button is clicked, but i want to update an object.
Thank you!
2
Answers
Move the
getUser
function outside of theuseEffect
hook. You should not define functions inside of it.Then invoke
getUser
insideuseEffect
like this:Also you should await the call of
handleLogin
. Every async function should be awaited.Let me know if this works for you.
You’re calling getUser inside a useEffect that depends on the user state. This creates a circular dependency because getUser updates the user state, which triggers the useEffect to run again. This can lead to unexpected behavior
React state updates are asynchronous. This means that after calling setUser(data), the user state won’t be immediately updated. Any code that relies on the updated state should be placed in a useEffect that listens for changes to the user state.
Remove the useEffect that calls getUser: Since you’re calling getUser in response to a button press, you likely don’t need to call it in a useEffect hook