Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Hooks Idle Timeout for Functional Component

I have an application that requires an idle timeout that first warns the user that they will be logged out in one minute, then logs the user out after the one minute has expired.

I have had success using a class component as demonstrated in the following post:

Session timeout warning modal using react

I am moving the code for my application over to React Hooks but I'm having a hard time moving this code over. I have tried the following:

const [signoutTime, setSignoutTime] = useState(0);
let warnTimeout;
let logoutTimeout;

const setTimeout = () => {
  warnTimeout = setTimeout(warn, warningTime);
  logoutTimeout = setTimeout(logout, signoutTime);
};

const clearTimeout = () => {
  if (warnTimeout) clearTimeout(warnTimeout);
  if (logoutTimeout) clearTimeout(logoutTimeout);
};

useEffect(() => {
  setWarningTime(10000);
  setSignoutTime(15000);
  const events = [
    'load',
    'mousemove',
    'mousedown',
    'click',
    'scroll',
    'keypress'
  ];

  const resetTimeout = () => {
    clearTimeout();
    setTimeout();
  };

  for (var i in events) {
    window.addEventListener(events[i], resetTimeout);
  }

  setTimeout();
});

const warn = () => {
  console.log('Warning');
};

const destroy = () => {
  console.log('Session destroyed');
};

In the end, I would like for a modal to appear to warn the user of impending logout. If the user moves the mouse, clicks, etc (see events) then the timer resets. If the user clicks on the button in the modal the timer is reset.

Thanks so much for the help!

like image 708
Chris Christensen Avatar asked Aug 07 '19 16:08

Chris Christensen


1 Answers

Try this

mport React, { useEffect, useState } from 'react';
    const LogoutPopup = () => {
        const [signoutTime, setSignoutTime] = useState(10000);
        const [warningTime, setWarningTime] = useState(15000);
        let warnTimeout;
        let logoutTimeout;

        const warn = () => {
            console.log('Warning');
        };
        const logout = () => {
            console.log('You have been loged out');
        }

        const destroy = () => {
            console.log('Session destroyed');
        }
        const setTimeouts = () => {
            warnTimeout = setTimeout(warn, warningTime);
            logoutTimeout = setTimeout(logout, signoutTime);
        };

        const clearTimeouts = () => {
            if (warnTimeout) clearTimeout(warnTimeout);
            if (logoutTimeout) clearTimeout(logoutTimeout);
        };

        useEffect(() => {

            const events = [
                'load',
                'mousemove',
                'mousedown',
                'click',
                'scroll',
                'keypress'
            ];

            const resetTimeout = () => {
                clearTimeouts();
                setTimeouts();
            };

            for (let i in events) {
                window.addEventListener(events[i], resetTimeout);
            }

            setTimeouts();
            return () => {
                for(let i in events){
                    window.removeEventListener(events[i], resetTimeout);
                    clearTimeouts();
                }
            }
        },[]);


        return <div></div>
    }
    export default LogoutPopup;
like image 101
Davit Avatar answered Oct 21 '22 10:10

Davit