Bzx naga
Bzx naga

Reputation: 169

UseEffect change is not instant ? But it still render somehow

I wanted to login not from function but from useState statement change, if login and fetch status is true, then User can get API. The problem that I noticed were

  1. Those changes wasn't instant
  2. Even tho it's not instant (via console log it was still false) but the return, if login == true, still render.

Question is , what is the best practice for this situation ? Is it possible not to creating new function / only using useEffect?

The problem is in useState, setLoginStatus , setFetchStatus , that doesnt change statement from FALSE to TRUE (via console log) but it does render that requires the statement to be TRUE. If it changes those statement to be true it will run the useEffect, right ?

      export default function TabOneScreen ({navigation}) {
        const [loginStatus,setLoginStatus] = useState(false)
        const [fetchStatus,setFetchStatus] = useState(false)


       function Login(){
        ////// this is the login button
        console.log('stating login dan fetch')  
        setLoginStatus(true)
        setFetchStatus(true)
        LoginSucess()
      }
    
      useEffect(()=>{
        console.log(fetchStatus,loginStatus)
        if (loginStatus == true && fetchStatus == true){
          console.log(login sucess , fetching API)
          gettingAPI()
        }
      },[fetchStatus])

    if(loginStatus==true) {
    return(
      <View style={styles.loadingContainer}>
        <View style={styles.etcContainer}>
        {loadingView == false ? 
          <View><Text style={{color:'#008080'}}>Fetching...{loginStatus}</Text></View> : 
          <View><Text style={{color:'#008080'}}>If fetching persist more than 10s, contact operator</Text></View>}
        </View>
        <LoadingScreen/>
        <View style={styles.etcContainer}>
        {loadingView == false ? 
          <View></View> : 
          <View></View>}
        </View>
      </View>
    )
    } else{
    <View style={styles.loginButton1}>
        <TouchableOpacity 
            onPress={()=>Login()}
            color="#aaa"
            style = {styles.buttonLogin}
        >
        <View style={styles.loginButton2}>
        <Text  style={[{color:'white' , fontWeight: 'bold'},gS.fontSize24]}> Login </Text>
        </View>
        </TouchableOpacity>
      </View>
      }
    }

Upvotes: 0

Views: 259

Answers (2)

b3hr4d
b3hr4d

Reputation: 4558

i think it would be easier of u do it like this :

export default function TabOneScreen() {
  const [loginStatus, setLoginStatus] = useState(false);
  const [fetchStatus, setFetchStatus] = useState(false);

  function Login() {
    setLoginStatus(true);
    setFetchStatus(true);
  }

  useEffect(() => {
    console.log(fetchStatus, loginStatus);
    if (loginStatus && fetchStatus) {
      setTimeout(()=>{
         alert("login sucess ,fetching API"); 
          setLoginStatus(false);
          setFetchStatus(false);
      }, 1000);
    }
  }, [fetchStatus, loginStatus]);
  
    return (
      <View style={styles.container}>
        <View style={styles.buttonContainer}>
        {loginStatus?
        <View>
          <Text style={{color:'#008080'}}>Fetching...{loginStatus}</Text>
        </View> :
          <Button
            onPress={()=>Login()}
            title="Press Me"
          />}
        </View>
      </View>
    );
  }

Expo

Upvotes: 1

Bzx naga
Bzx naga

Reputation: 169

I'm using the same code, sorry its a bug idk if its from expo or react. The useEffect re-render as intended

Upvotes: 0

Related Questions