Best way to have an inactivity timer in react-query?
Essentially, if a user is inactive for 30 minutes we want to prompt them to remain active or automatically log them out. My question is what's the best approach to restart a countdown timer when query/mutations happen?
- My own
QueryCache/MutationCache with onSuccess calling to a provider/store?
- Subscribe within my component using mutationCache/queryCache.subscribe?
- Something else?
I was using this article as my reference, which is what I used for our ErrorModal popup: https://tkdodo.eu/blog/react-query-error-handling#the-global-callbacksReact Query Error Handling
After covering the sunshine cases of data fetching, it's time to look at situations where things don't go as planned and "Something went wrong..."
6 Replies
optimistic-gold•3y ago
I would probably do this at a lower level, when actually sending the requests, inside the query function.
You could wrap
fetch (or whatever you use to send a request) into a function that would also reset the timer.rare-sapphireOP•3y ago
We use
ky for our requests and I thought of doing afterResponse but then that creates the difficulty of being outside of a React component, which I don't know how to best solve
In my React DOM I basically have {isExpiring && <MyModal />} where isExpiring is set to true once our timeout is hit via useTimeout from usehooks-ts. If I'm doing something in ky's afterResponse I couldn't find a good way to do React things from outside a component. It seems pretty frowned upon (which I why I tried moving the logic into react-query)?optimistic-gold•3y ago
I would probably use the window for this. Here is a working example: https://codesandbox.io/s/gallant-sun-vsrvf4?file=/src/index.js
A callback to refresh the timer is placed on the window and the custom fetch function can trigger it every time it runs. Since that callback is created inside of react, we are still able to set the
isExpired state inside it thanks to closure. And the isExpired state value is propagated through context.
I suspect something can be done using useSyncExternalStore() tooCodeSandbox
gallant-sun-vsrvf4 - CodeSandbox
gallant-sun-vsrvf4 using axios, react, react-dom, react-query, react-scripts, stop-runaway-react-effects, styled-components, usehooks-ts
rare-sapphireOP•3y ago
The problem is our sessions are stored server side so I need to actually touch the server to truly remain active. This effort is rewritting a very old AngularJS project in React so I could give some details on how the old system works if that'd help.
optimistic-gold•3y ago
Does this change the timer logic?
rare-sapphireOP•3y ago
It does a little but I looked at your example closer and I think it gives me an idea
Okay so I've moved my logic into ky like I originally wanted and since we're using zustand I'll have something like
useAuthStore.getState().restartTimer()