React Idle Timer concept illustration with computer screen, clock, and sleeping cat

Idle Hands Are the Devil's Playground: Taming User Inactivity with React Idle Timer

The Orange Cat
The Orange Cat

React Idle Timer is a powerful library that allows developers to detect and respond to user inactivity in React applications. It provides a flexible and efficient way to manage idle states, implement session timeouts, and enhance both security and user experience. Whether you’re building a complex dashboard, a secure financial application, or simply want to optimize resource usage, React Idle Timer offers the tools you need to handle user engagement effectively.

Features

React Idle Timer comes packed with a variety of features that make it a versatile choice for managing user activity:

  • Cross-browser compatibility: Works seamlessly across different browsers and devices.
  • Customizable events: Ability to specify which user actions should reset the idle timer.
  • Configurable timeouts: Set custom durations for idle and prompt states.
  • React Hooks support: Easy integration with functional components using hooks.
  • TypeScript support: Full type definitions for enhanced development experience.
  • Debounce and throttle: Built-in mechanisms to optimize performance.
  • Passive event listeners: Improved scrolling performance on mobile devices.
  • Server-side rendering (SSR) support: Compatible with server-rendered React applications.

Installation

To get started with React Idle Timer, you can install it using npm or yarn:

npm install react-idle-timer

or

yarn add react-idle-timer

Basic Usage

Simple Idle Detection

Let’s start with a basic example of how to use React Idle Timer to detect when a user becomes idle:

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

const IdleTimerComponent: React.FC = () => {
  const handleOnIdle = () => {
    console.log('User is idle');
    // Perform actions like showing a warning modal or logging out the user
  };

  const { getRemainingTime, getLastActiveTime } = useIdleTimer({
    timeout: 1000 * 60 * 15, // 15 minutes
    onIdle: handleOnIdle,
    debounce: 500
  });

  return (
    <div>
      <p>Time remaining: {Math.ceil(getRemainingTime() / 1000)} seconds</p>
      <p>Last active: {new Date(getLastActiveTime()).toISOString()}</p>
    </div>
  );
};

In this example, we’re using the useIdleTimer hook to create an idle timer that triggers after 15 minutes of inactivity. The onIdle callback is called when the user becomes idle, allowing you to perform actions such as showing a warning or logging out the user.

Resetting the Timer

You can also manually reset the timer when needed:

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

const ResetableTimerComponent: React.FC = () => {
  const { reset } = useIdleTimer({
    timeout: 1000 * 60 * 5, // 5 minutes
    onIdle: () => console.log('User is idle'),
  });

  return (
    <button onClick={() => reset()}>
      Reset Idle Timer
    </button>
  );
};

This component provides a button that, when clicked, resets the idle timer. This can be useful in scenarios where you want to manually extend the user’s active session.

Advanced Usage

Custom Events and Element Binding

React Idle Timer allows you to specify custom events and bind the timer to specific DOM elements:

import React, { useRef } from 'react';
import { useIdleTimer } from 'react-idle-timer';

const CustomEventsComponent: React.FC = () => {
  const containerRef = useRef(null);

  const { start, pause, resume } = useIdleTimer({
    timeout: 1000 * 60 * 10, // 10 minutes
    element: containerRef,
    events: ['mousemove', 'keydown', 'wheel', 'DOMMouseScroll', 'mousewheel', 'mousedown', 'touchstart', 'touchmove', 'MSPointerDown', 'MSPointerMove'],
    onIdle: () => console.log('User is idle'),
    onActive: () => console.log('User is active'),
    onAction: () => console.log('User did something')
  });

  return (
    <div ref={containerRef}>
      <button onClick={() => start()}>Start</button>
      <button onClick={() => pause()}>Pause</button>
      <button onClick={() => resume()}>Resume</button>
    </div>
  );
};

This example demonstrates how to bind the idle timer to a specific DOM element and listen for custom events. It also showcases the start, pause, and resume methods for controlling the timer.

Implementing a Session Timeout

Here’s a more complex example that implements a session timeout with a warning prompt:

import React, { useState } from 'react';
import { useIdleTimer } from 'react-idle-timer';

const SessionTimeoutComponent: React.FC = () => {
  const [isPrompted, setIsPrompted] = useState(false);

  const handleOnIdle = () => {
    setIsPrompted(false);
    console.log('Session expired. Logging out...');
    // Implement logout logic here
  };

  const handleOnActive = () => {
    setIsPrompted(false);
  };

  const handleOnPrompt = () => {
    setIsPrompted(true);
  };

  const { getRemainingTime, activate } = useIdleTimer({
    timeout: 1000 * 60 * 20, // 20 minutes
    promptTimeout: 1000 * 60 * 5, // Show prompt 5 minutes before timeout
    onIdle: handleOnIdle,
    onActive: handleOnActive,
    onPrompt: handleOnPrompt,
    debounce: 500
  });

  const handleStayActive = () => {
    activate();
  };

  return (
    <div>
      {isPrompted && (
        <div>
          <p>Your session is about to expire. Do you want to stay signed in?</p>
          <button onClick={handleStayActive}>Yes, keep me signed in</button>
        </div>
      )}
      <p>Time remaining: {Math.ceil(getRemainingTime() / 1000)} seconds</p>
    </div>
  );
};

This component implements a session timeout feature with a warning prompt. It shows a message to the user 5 minutes before the session expires, giving them the option to extend their session.

Using with Class Components

While hooks are the preferred method in modern React, React Idle Timer also supports class components through a higher-order component:

import React from 'react';
import { withIdleTimer, IdleTimerProps } from 'react-idle-timer';

interface AppProps extends IdleTimerProps {
  // Your custom props here
}

class App extends React.Component<AppProps> {
  onIdle = () => {
    console.log('User is idle');
  }

  onActive = () => {
    console.log('User is active');
  }

  onAction = () => {
    console.log('User performed an action');
  }

  render() {
    return (
      <div>
        <h1>My App</h1>
        <p>Idle Timer is running...</p>
      </div>
    );
  }
}

export default withIdleTimer({
  timeout: 1000 * 60 * 15,
  onIdle: this.onIdle,
  onActive: this.onActive,
  onAction: this.onAction
})(App);

This example shows how to use the withIdleTimer higher-order component to add idle timer functionality to a class component.

Conclusion

React Idle Timer provides a robust and flexible solution for managing user activity and inactivity in React applications. From simple idle detection to complex session management, this library offers the tools needed to enhance both security and user experience. By leveraging its various features such as customizable events, configurable timeouts, and TypeScript support, developers can create more responsive and secure applications.

Whether you’re building a corporate dashboard, a banking application, or any system where user engagement tracking is crucial, React Idle Timer can be an invaluable addition to your toolkit. Its ease of use with both hooks and class components makes it accessible for projects of all scales and complexities.

As web applications continue to evolve, managing user sessions and activity becomes increasingly important. React Idle Timer stands out as a powerful ally in this endeavor, helping developers create more secure, efficient, and user-friendly React applications.

Comments