提问者:小点点

对未安装的组件进行反应状态更新


我是新的反应本机,我有一个错误,我不能理解,控制台发送一条消息说

警告:无法对已卸载的组件执行React状态更新。这是一个no-op,但它表示应用程序中存在内存泄漏。若要修复,请取消%s.%s中的所有订阅和异步任务,这是一个useEffect清理功能

我的代码是下一个

const AuthStack = createStackNavigator();

const LoginStack = () => {

    const initialLoginState = {
        isLoading: true,
        userName: null,
        userToken: null,
    };

    const loginReducer = (prevState, action) => {
        switch (action.type) {
            case 'RETRIEVE_TOKEN':
                return {
                    ...prevState,
                    userToken: action.token,
                    isLoading: false,
                };
            case 'LOGIN':
                return {
                    ...prevState,
                    userName: action.id,
                    userToken: action.token,
                    isLoading: false,
                };  
            case 'LOGOUT':
                return {
                    ...prevState,
                    userName: null,
                    userToken: null,
                    isLoading: false,
                };
        }
    };
    
    const [loginState, dispatch] = useReducer(loginReducer, initialLoginState);

    const authContext = useMemo(() => ({
        signIn: (userName, password) => {
            let userToken;
            userName = null;
            if ( userName == 'user' && password == 'pass' ) {
                userToken: 'irais';
            }
            dispatch({ type: 'LOGIN', id: userName, token: userToken });
        },
        signOut: () => {
            dispatch({ type: 'LOGOUT' });
        },
    }));

    useEffect(() => {
        setTimeout(() => {
            // setIsLoading(false)
            dispatch({ type: 'RETRIEVE_TOKEN', token: 'irais' });
        },1000);
    }, []); 
}

共2个答案

匿名用户

问题是“使用效果”。您需要返回一个清理函数,以确保任何效果都被正确处理。

 useEffect(() => {
        const handle = setTimeout(() => {
            // setIsLoading(false)
            dispatch({ type: 'RETRIEVE_TOKEN', token: 'irais' });
        },1000);
        
        return () => clearTimeout(handle);
    }, []); 

匿名用户

看一看你的use效应。它调度异步任务(超时),该任务更新组件状态(使用调度)。然后,您的组件可能已经在超时完成时挂载。解决方法是使用一个清除函数,它基本上是use效应的返回语句:

   useEffect(() => {
        const timeout = setTimeout(() => {
            // setIsLoading(false)
            dispatch({ type: 'RETRIEVE_TOKEN', token: 'irais' });
        },1000);

        return () => {
           clearTimeout(timeout);
        }
    }, []);