-
Assuming there is some session management implementation (or any other similar functionality like auto refresh, etc.)
it is easy to activate the session in a View component:
what is the way to set use intervals for
it seems to be not possible, there is not "set" parameter in Put that logic into View will solve the problem, but the View component might not exist at some point of time (can be different screen, etc.) and make View more complicated. And I'm looking for something like:
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
It's a good practice to try to have a single source of truth for state. No need for maintaining a separate atom if the session is active if you also have an atom for the remaining time; that could be derived state. For example: export const remainingTimeState = atom<number>({
key: 'remainingTime',
default: SESSION_TIMEOUT,
});
export const isSessionActiveState = selector<boolean>({
key: 'isSessionActive',
get: ({get}) => get(remainingTimeState) > 0,
}); As you mention, you shouldn't be setting state from selector accessors or render functions. You can update the countdown from a React effect or other async callback. function MyComponent() {
const startSession = useRecoilCallback(({set, reset}) => () => {
reset(remainingTimeState);
const interval = setInterval(() => {
set(remainingTimeState, remainingTime => {
const newTime = remainingTime - 1000;
if (newTime <= 0) {
clearInterval(interval);
}
return newTime;
}, 1000);
return <button onClick={restartSession}>Restart Session</button>;
} This is just a quick example of setting state, you'd want to protect against overlapping intervals and such of course. Hmm, actually, it might be nifty to build the countdown into the atom itself using an atom effect... export const remainingTimeState = atom<number>({
key: 'remainingTime',
default: SESSION_TIMEOUT,
effects_UNSTABLE: [
({setSelf}) => {
const interval = setInterval(() => {
setSelf(remainingTime => remainingTime <= 1000 ? 0 : remainingTime - 1000);
}, 1000);
return () => clearInterval(interval);
},
],
});
export const isSessionActiveState = selector<boolean>({
key: 'isSessionActive',
get: ({get}) => get(remainingTimeState) > 0,
}); |
Beta Was this translation helpful? Give feedback.
-
Hi @drarmstr thanks for quick feedback.
That's something I wanted to avoid, because in case if react navigation (or any other navigation) is used, you never know which screen is active and where to put the component with use effect (or put to all screens?). Or it can be a case when the component is not mounted at all (for example app went to background). But |
Beta Was this translation helpful? Give feedback.
It's a good practice to try to have a single source of truth for state. No need for maintaining a separate atom if the session is active if you also have an atom for the remaining time; that could be derived state. For example:
As you mention, you shouldn't be setting state from selector accessors or render functions. You can update the countdown from a React effect or other async callback.