I am trying to create a timer that is started once the app is in the background, and then when the app is called to the foreground again the app checks if it has been 15 minutes (for ease of testing I am using 15s currently). If it has the app logs the user out, else the timer resets.
If this is a dupe please refer me - I just couldn't find anything. I've been trying to work this out for a couple of days now.
Here is my thinking:
Here is my problem:
Things to note:
const rootNavigator = () => {
const dispatch = useDispatch()
const [loginTimer, setLoginTimer] = useState(Date.now())
useEffect(() => {
AppState.addEventListener('change', handleAppStateChange)
return (() => {
AppState.removeEventListener('change', handleAppStateChange)
})
}, [])
const handleAppStateChange = (state) => {
if (state === "inactive" || state === "background") {
setLoginTimer(Date.now())
}
if (state === "active") {
if (Date.now() - loginTimer < 15000) {
setLoginTimer(Date.now())
} else if (Date.now() - loginTimer >= 15000) {
dispatch(logout())
}
}
}
return (
<SomeComponent />
...
)
}
I am almost certain this is a pretty basic error I am running into because my understanding of how this is meant to be handled is not yet well formed enough.
Thanks in advance.
The problem is coming from your reference to useState
data in the callback function handleAppStateChange()
. The callback for AppState.addEventListener
is registered when the component mounts, but a snapshot of the current state is used for that callback each time it is called, and therefore, it will not be reactive in the way you would like.
The good news is that there are a number of ways to fix this issue, and some of those are explained in nice detail in this great answer here .
My solution, using information from Jacob K's link. It was very simple in the end and I got it down to an even more succinct statement. Can probably use a ternary, but this works just fine.
const rootNavigator = () => {
const dispatch = useDispatch()
const timer = useRef(Date.now())
useEffect(() => {
AppState.addEventListener('change', handleAppStateChange)
return (() => {
AppState.removeEventListener('change', handleAppStateChange)
})
}, [])
const handleAppStateChange = (state) => {
if (state === "inactive" || state === "background") {
timer.current = Date.now()
}
if (state === "active" && (Date.now() - timer.current > 15000)) {
dispatch(logout())
}
}
return (
<SomeComponent />
...
)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.