首页 > 解决方案 > 无法对未安装的组件执行 React 状态更新。这是一个无操作,但它表明您的应用程序中存在内存泄漏

问题描述

我想登录我的应用程序,但是当我第一次登录时它可以正常工作,但是一旦我从我的应用程序注销并再次尝试登录,我就会收到以下错误“无法在卸载组件上执行状态更新”。即使第二次它也进入了应用程序,但出现了不应该存在的错误。只有一次它可以正常工作。

/*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, 

标签: react-native

解决方案


推荐阅读