0

I want to login to my app but when I first login it works correctly but once I logout from my app and again try to login I get the following error 'Can't perform a state update on an unmount component'. Even though second time it also enters in the app but with the error which should be not there. Only one time it works correctly.

/*Component*/
const LoginScreen = props => {
    let  _isMounted = false;
    const [isLoading , setIsLoading] = useState(false); 
    const [error , setError] = useState();
    const [token , setToken] = useState();
    const [url , setUrl] = useState({});
    const dispatch = useDispatch();

/*Receiving the token*/    
    useEffect(() => {
       let  _isMounted = false;
        const tokenReceive = () => {
            if(Object.entries(url).length !== 0)
            {  
                const getTokenFromUrl = url['url'].split('=')[1].split('&')[0];
                if(getTokenFromUrl !== '')
                {

                    setToken(getTokenFromUrl)
                } 
        }
    }    
        tokenReceive();
        return(() => { 

          _isMounted = true
        } )
    }, [url ])

/*Dispatching after receiving token*/    
    useEffect(() =>{  
        _isMounted = true;
        const loginHandler = async ()=> {
            if(token !== undefined)
            {
            setError(null)
            setIsLoading(true);
            try{
                await dispatch(authActions.login(token))

                // if(_isMounted){
                // props.navigation.navigate('afterAuth')
                // }
            }
            catch(err)
            {

                setError(err.message)

            }
            setIsLoading(false)
            if(_isMounted){
                props.navigation.navigate('afterAuth')
                }
        }
    } 
        loginHandler()
        return(() => {

             _isMounted = false
        } )
    } , [token  ])

 /*If any error occur*/   
    useEffect(() => {
        if (error) {
              Alert.alert('An error occured',error,[{text : 'Okay'}]);  
        }
        return(() => {
            console.log('Error'),
             error 
        })
    } , [error])


/*Event listener when url changes*/    
    useEffect(() => {
     Expo.Linking.addEventListener('url', (url) => {         

            setUrl(url);

    })
    return () => {
            Expo.Linking.removeEventListener('url' , (url) => {
                setUrl(url)
            })
    };
    } , [])

    const prefix = Expo.Linking.makeUrl('token');
    const _handlePressButtonAsync = async () => {
        let result = await WebBrowser.openBrowserAsync(`https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=**********&response_type=id_token&redirect_uri=${prefix}&scope=openid email profile&response_mode=fragment&state=*****&nonce=****`);   
      };

    return(
        <ScrollView >
            <TouchableWithoutFeedback onPress={() => {Keyboard.dismiss()}} >
                <View style={styles.screen}> 
                    <CircleDiv style={styles.userlogoDiv}>
                        <View style={styles.userLogo}>
                            <AntDesign name="user" size={RFValue(39)} color='#4D4848'/>
                        </View>
                    </CircleDiv>
                    <BackgroundUpper style={styles.upperDiv}>
                        <LogoLong style={ {marginTop :  RFValue(100)}}/>
                    </BackgroundUpper>
                    <BackgroundLower >
                        <ScrollView style={{ flex : 1 } } decelerationRate='fast' >
                            <KeyboardAvoidingView behavior='position' keyboardVerticalOffset={Dimensions.get('screen').height / RFValue(10)}>
                                <View style={styles.loginDiv}>
                                    <View style={styles.headingDiv}>
                                        <Text style={styles.heading}>LOGIN</Text>
                                    </View>
                                    <View style={styles.buttonDiv}>
                                        <TouchableOpacity>
                                           {!isLoading ? <Button
                                                style={styles.button}
                                                title='LOGIN'
                                                color= '#00B49D'
                                                //onPress = {navigate}
                                                onPress={_handlePressButtonAsync}
                                            /> : <ActivityIndicator size="small" color={Colors.GREEN}/>}
                                        </TouchableOpacity>
                                    </View>
                                    <View style={styles.forgetDiv}>
                                        <Text style={styles.forget}>Forget Password</Text>
                                    </View>     
                                </View>
                            </KeyboardAvoidingView>
                        </ScrollView>
                    </BackgroundLower>
                </View>
            </TouchableWithoutFeedback>
        </ScrollView>
    )
};


Error - Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in %s.%s, a useEffect cleanup function, 
Prajwal
  • 95
  • 10
  • Perhaps use `await loginHandler()` in `/*Dispatching after receiving token*/`? – jmullercuber Oct 06 '19 at 07:02
  • also in `/*Event listener when url changes*/` you define the event handler twice. Just define it once and do `Expo.Linking.addEventListener('url', handler)`/`Expo.Linking.removeEventListener('url', handler)` – jmullercuber Oct 06 '19 at 07:06
  • where I have define event handler twice? One in useEffect and one in return for cleanup..it is not correct? – Prajwal Oct 06 '19 at 07:38
  • Oh thank you....I have resolved the issue :-) @jmullercuber – Prajwal Oct 06 '19 at 07:43
  • One more think as I am using microsoft to login to my app...it by default save my credentials and if I want to login with other credentials I have to delete the history from my browser. Can u help me with this also? – Prajwal Oct 06 '19 at 07:46
  • Glad to have helped. Hmm, I'm not sure about your other problem. Maybe: https://stackoverflow.com/questions/41217019/how-to-prevent-a-browser-from-storing-password/41217255 or posting as a different question would help. Best of luck with your app – jmullercuber Nov 03 '19 at 04:39
  • @jmullercuber Thank you for replying...I have resolved the issue :-) – Prajwal Nov 03 '19 at 09:22
  • @Prajwal I am having a similar issue here with your first question - https://stackoverflow.com/questions/63536154/useeffect-cant-perform-a-react-state-update-on-an-unmounted-component-this-is do you have updated code to show resolution? cheers :) – roshambo Aug 23 '20 at 01:59

0 Answers0