首页 > 解决方案 > UserInactivity 组件连续调用函数,而不是定时调用

问题描述

我正在使用react-native-user-inactivity来触发silentRenew和更新我的应用程序的访问令牌,如果我当前的令牌过期而用户仍在使用它来保存他们被踢出。这是我的应用程序中唯一调用该函数的地方,但调用频率比 30 秒间隔要频繁得多timeForInactivity={30000}

silentRenew似乎接连开火。我怎样才能让silentRenew每30秒触发一次,而不是向登录服务发送垃圾邮件?

import UserInactivity from 'react-native-user-inactivity';
import BackgroundTimer from 'react-native-user-inactivity/lib/BackgroundTimer';
    const UserActivityMonitor = (props) => {
        const { children } = props;
        ...
        const handleIsActive = async (isActive) => {
            ...
                
                    try {
                        const success = await silentRenew();
                        console.log(success)
                        if (success === true) {
                            setValidToken(success);
                        }
                    } catch (e) {
                        logger.error(
                            'Error occured while monitoring user activity',
                            e,
                        );
                    }
              
        };
    
        return (
            <>
                <UserInactivity
                    timeoutHandler={BackgroundTimer}
                    timeForInactivity={30000}
                    onAction={handleIsActive}
                >
                    {children}
                </UserInactivity>
            </>
        );
    };
    export { UserActivityMonitor };

沉默更新:

const silentRenew = async () => {
    try {
        const authdata = await getItem(AUTH_DATA);
        if (authdata) {
            const {
                refreshToken,
            } = JSON.parse(authdata);
            if (refreshToken) {
                await refreshAuthToken(refreshToken);
                return true;
            }
            return false;
        }
        return false;
    } catch (e) {
        logger.error('Error occurred while slient renew', e);
        return false;
    }
};

应用程序.js:

 <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
      <AppContextProvider>
        <NetworkProvider
          pingInterval={toNumber(networkCheckConfig.pingInterval)}
          pingServerUrl={networkCheckConfig.pingServerUrl}
        >

          <NavigationContainer
            initialState={initialState}
            ref={navigationRef}
            onReady={() => {
              isReadyRef.current = true;
            }}
            onStateChange={(state) => {
              setItem(NAVIGATION_STATE, JSON.stringify(state));
            }}
          >
            <UserActivityMonitor>
              <AppRootStack />
            </UserActivityMonitor>
          </NavigationContainer>
        </NetworkProvider>
      </AppContextProvider>
      </PersistGate>
    </Provider>

标签: javascriptreact-native

解决方案


好的,所以我在阅读图书馆的文档后做了一些测试,似乎onAction每次用户“不活动”时都会被解雇(当没有交互的时​​间超过timeForInactivity),但每次实际上都有一个相互作用。用户活动的真正指标是传递isActive参数的值。

知道这一点并假设您只想silentRenew在用户处于活动状态时每 30 秒运行一次,您必须进行一些更改:

import React, {useCallback, useRef, useEffect} from 'react';
import UserInactivity from 'react-native-user-inactivity';
import BackgroundTimer from 'react-native-user-inactivity/lib/BackgroundTimer';

const timeForInactivity = 30000;
const refreshInterval = 30000;

const UserActivityMonitor = (props) => {
    const {children} = props;

    const isActiveRef = useRef(true);

    const handler = useCallback((isActive) => {
        isActiveRef.current = isActive;
    }, []);

    useEffect(() => {
        const interval = setInterval(() => {
            if (isActiveRef.current) {
                // REFRESH TOKEN HERE.
            }
        }, refreshInterval);

        return () => {
            clearInterval(interval);
        };
    }, []);

    return (
        <>
            <UserInactivity
                timeoutHandler={BackgroundTimer}
                timeForInactivity={timeForInactivity}
                onAction={handler}>
                {children}
            </UserInactivity>
        </>
    );
};

export {UserActivityMonitor};

推荐阅读