javascript - 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>
解决方案
好的,所以我在阅读图书馆的文档后做了一些测试,似乎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};
推荐阅读
- saml-2.0 - 如何在 ruby-saml 中指定 SAML 加密证书?
- docker - 如何在 Heroku 上使用 Docker 运行 2 个不同的控制台?
- c# - 这行代码在做什么?(编辑 .txt 文件中的一行 - ASP.NET MVC / C#)
- ios - SwiftUI adjustsFontSizeToFitWidth 等价
- flutter - Flutter iOS Build Error Multiple Commands product Runner.app/Runner
- javascript - NextJs 获取下一页点击项的内容
- linux - Linux 信号量生命周期
- javascript - 为什么这里的值没有被函数改变?
- python - 从谷歌日历 API 中检索摘要信息
- excel - 你能帮我扩展这个公式吗