skip to Main Content

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


  1. Move the getUser function outside of the useEffect hook. You should not define functions inside of it.
    Then invoke getUser inside useEffect like this:

    await getUser();
    

    Also you should await the call of handleLogin. Every async function should be awaited.

    Let me know if this works for you.

    Login or Signup to reply.
  2. 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

        const getUser = async (email) => { your code }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search