14

I need to know if there is any API in REACT JS or HTML5 which provides the functionality of auto-log off when a user is inactive. My code is below I don't know what is wrong it is giving me the error startTimer is not defined and unnecessary binding. Please tell me where I am going wrong

import React from 'react';
import ReactDOM from 'react-dom';
import './App.css';

class Toogle extends React.Component {
  constructor(props) {
    super(props);
    //step 1
    this.handleClick = this.handleClick.bind(this);
    this.startTimer=this.startTimer.bind(this)
  }
            
  handleClick() {
    console.log('Button is clicked');
    
    //  clearTimeout(timeoutTimer);
    startTimer() {
      var timeoutTimer = setTimeout(function() {
        window.location.href = '#/security/logout';
      }.bind(this), 1000);  
    }
  }

  render() {
    return (
      <div onMouseMove={this.handleClick}>
        Move the cursor over me
      </div>
    );
  }
}

ReactDOM.render(
  <Toogle />,
  document.getElementById('root')
);
Orlyyn
  • 2,296
  • 2
  • 20
  • 32
Gitesh
  • 346
  • 2
  • 4
  • 14
  • Very broad question.. not really SO worthy. You have to program such functionality yourself or find a authentication package. – BradByte Nov 30 '16 at 13:25

3 Answers3

17

Accepted answer may do the job for you , but the time between navigating routes is not the real "in-active" time.

react-idle can do this , read the documentations and you can do it the way it should be.

Omid Navy
  • 272
  • 2
  • 12
  • 8
    react-idle project was removed from Github. This alternative do the same trick https://www.npmjs.com/package/react-idle-timer – Camilo Apr 29 '19 at 14:53
7

If you are using the react-router library to add front-end route configuration, you can fire a function whenever a user navigates to another page.

<Route path="/" onEnter={onUserNavigate} onChange={onUserNavigate}>
    ...
</Route>

Then you can have your event handler function calculate the time between to user navigations.

N.B. This is only a skeleton code (serves as a prototype for your actual method)

function onUserNavigate() {
    let idleTime = getCurrentTime() - getPreviousNavTime();
    storeCurrentNavTime();
    if (idleTime > ALLOWED_IDLE_TIME)
        window.location.href = '#/security/logout';
}

So, the above function assumes that,

  • You have a method to get the current time (getCurrentTime function)
  • You have a method to store and get timestamps when a user navigates to a page
  • You have a constant called ALLOWED_IDLE_TIME to store the minimum allowed idle time the user spends between two pages.
  • You have a logout URL (valued #/security/logout in the example code above)
  • The user isn't expected to interact with the page without navigating through the react-router paths. For example, the user may interact with the page using a browser console beyond the allowed idle time.

For timestamp related calculations and methods you can use any JavaScript library like momentjs

Hope that helped.

UPDATE There is an unnecessary binding around the part }.bind(this), 1000); Just remove the .bind(this) segment.

Plus, the startTimer() { fragment should give you syntax error. For that you should remove the startTimer() { line and its corresponding closing } line

Leone
  • 3,258
  • 3
  • 22
  • 28
  • Thanks for your help.I have written the code and edited my question.Please see where am i wrong – Gitesh Dec 02 '16 at 06:47
  • @Gitesh There might be some syntax error in your code. Around `}.bind(this), 1000);` I don't think you need the `.bind(this)` part. – Leone Dec 02 '16 at 14:37
  • Thanks for your help. – Gitesh Dec 05 '16 at 10:03
  • Be aware that onEnter was removed on react router 4. Also, this approach has a problem, if your user spent much time in the same route filling a form or clicking things, will be suddenly logged out while using the app. Navigating through routes is not the only activity a user can do. I think the other answer must be the accepted one. – Camilo Apr 29 '19 at 15:01
  • @Leone.. "you can fire a function whenever a user navigates to another page." This is not a good indicator of inactivity. Within the one page, the user may mount, unmount many components, and do lots of activity without needed to navigate again to another page ?! EDIT just like what Camilo said in the comment above ! – joedotnot May 14 '20 at 09:03
  • This is how to detect route change in `react-router v6`: https://stackoverflow.com/questions/45373742/detect-route-change-with-react-router/62389224#62389224 – ge333 Jun 24 '22 at 13:44
0

Simplest approach is to use the react-idle-timer package. Use the code below at the App.js level:

import { useIdleTimer } from 'react-idle-timer';

export default function App() {

  const onIdle = () => {
    console.log('fires after 10 minutes');
    //insert any custom logout logic here
  }

  const { getRemainingTime } = useIdleTimer({
    onIdle,
    timeout: 10 * 60 * 1000, //10 minute idle timeout
  })
  
  return (  
    //your App code
  );

}

Docs: https://idletimer.dev/docs/features/idle-detection

NPM: https://npmjs.com/package/react-idle-timer

GavinBelson
  • 2,514
  • 25
  • 36