Session timeout warning modal using react

31,637

Solution 1

You can create a higher order component like this and can pass child component through higher order component

HOC:

`// code

export default function(ComposedClass) {
  class AutoLogout extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        warningTime: 1000 * 60 * 10,
        signoutTime: 1000 * 60 * 15,
      };
    }

    componentDidMount() {
      this.events = [
        'load',
        'mousemove',
        'mousedown',
        'click',
        'scroll',
        'keypress'
      ];

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

      this.setTimeout();
    }

    clearTimeoutFunc = () => {
      if (this.warnTimeout) clearTimeout(this.warnTimeout);

      if (this.logoutTimeout) clearTimeout(this.logoutTimeout);
    };

    setTimeout = () => {
      this.warnTimeout = setTimeout(this.warn, this.state.warningTime);
      this.logoutTimeout = setTimeout(this.logout, this.state.signoutTime);
    };

    resetTimeout = () => {
      this.clearTimeoutFunc();
      this.setTimeout();
    };

    warn = () => {
      window.alert("You will be logged out automatically in 1 minute")
      console.log('You will be logged out automatically in 1 minute.');
    };

    logout = () => {
      // Send a logout request to the API
      console.log('Sending a logout request to the API...');
      this.destroy();
    };

    destroy = () => {
     //clear the session
      browserHistory.push('/');
      window.location.assign('/');
    };

    render() {

      return (
        <div>
          <ComposedClass {...this.props} />
        </div>
      );
    }
  }
}

`

You can wrap this HOC to all those component in which you want to give user warning due to inactivity, in routing file

<Route path="/test" component={HOC(comonent)} />

in above code component will be the page where you want to add this functionality.

Solution 2

If you want to achieve same with Package, then you can write below code using React Idle Timer Package

npm i react-idle-timer

import React from 'react'
import { useIdleTimer } from 'react-idle-timer'
import { useHistory } from 'react-router'

const SESSION_IDEL_MINUTES = 4;

const AutoLagoutTimer = (props: any) => {
    const { ComposedClass } = props
    const history = useHistory()

    const handleOnIdle = (event: any) => {
        // SHOW YOUR MODAL HERE AND LAGOUT
        console.log('user is idle', event)
        console.log('last active', getLastActiveTime())
        history.push("/lagout")
    }

    const {getLastActiveTime } = useIdleTimer({
        timeout: 1000 * 60 * SESSION_IDEL_MINUTES,
        onIdle: handleOnIdle,
        debounce: 500,
    })

    return <ComposedClass />
}

export default AutoLagoutTimer;

And for all your protected routes you can wrap with this component like below

     <Route path={"/dashboard"}>
        <AutoLagoutTimer ComposedClass={Dashboard} />
    </Route>
Share:
31,637
abhi
Author by

abhi

Front End developer using HTML, CSS, React, Redux and jQuery. Another focus area is A11Y accessibility.

Updated on August 26, 2020

Comments

  • abhi
    abhi almost 4 years

    I have a requirement to display timeout warning modal after 13 mins of inactivity and end session after 15 mins if user takes no action. I need to achieve this using reactjs. I checked react-timeout at https://www.npmjs.com/package/react-timeout#react-classic-verbose, but that didn't help. If anyone knows of a way to do this, please share with me.

  • Woodchuck
    Woodchuck over 4 years
    Do you have a working example that demos something like this?
  • Woodchuck
    Woodchuck over 4 years
    Doesn't an alert box halt the event loop, preventing the logout?
  • MLissCetrus
    MLissCetrus over 4 years
    stackoverflow.com/users/3368818/j-woodchuck - did you get this work ? If so, can you post your solution?
  • MLissCetrus
    MLissCetrus over 4 years
    I am getting this: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
  • Hazed 2.0
    Hazed 2.0 over 3 years
    how would I call a dispatch action from logout?