UserInactivity 组件连续调用函数,而不是定时间隔

时间:2021-07-19 17:49:48

标签: javascript react-native

我正在使用 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 };

silentRenew:

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;
    }
};

App.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>

1 个答案:

答案 0 :(得分:0)

好的,所以我在阅读了图书馆的 documentation 后做了一些测试,似乎 onAction 旨在在每次用户“不活动”时被触发(当有一段时间没有交互时比 timeForInactivity),而且每次实际上都有交互。用户活动的真正指标是传递的 isActive 参数的值。

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

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};