SupremeTechnopriest/react-idle-timer

View on GitHub
docs/pages/docs/api/with-idle-timer.mdx

Summary

Maintainability
Test Coverage
---
title: withIdleTimer
description: Higher order component for class-based React applications
---

Higher order component for class-based React applications. The `withIdleTimer` 
HOC takes [IIdleTimerProps](/docs/api/props) as configuration options and exposes
[IIdleTimer](/docs/api/methods) as props to the wrapped component.

## Import

```js
import { withIdleTimer } from 'react-idle-timer'
```

## Usage

There are a few ways to use the higher-order component, but at its core, the component
passed into `withIdleTimer` is enriched with the [IIdleTimer](/docs/api/methods) interface. 
The most common use cases are outlined below.

### IdleTimer Component

The first way is to create your own IdleTimer component and use it just like the 
v4 component.

Create the `IdleTimer` component that extends `IdleTimerComponent` instead of `Component`.

```js
import { Component } from 'react'
import { withIdleTimer } from 'react-idle-timer'

class IdleTimerComponent extends Component {
  render () {
    return this.props.children
  }
}

export const IdleTimer = withIdleTimer(IdleTimerComponent)
```

Use the `IdleTimer` component.

```js
import { Component } from 'react'
import { IdleTimer } from './IdleTimer'

export class App extends Component {
  constructor (props) {
    super(props)
    this.idleTimer = null
    this.onPresenceChange = this.onPresenceChange.bind(this)
    this.onPrompt = this.onPrompt.bind(this)
    this.onIdle = this.onIdle.bind(this)
    this.onAction = this.onAction.bind(this)
    this.onActive = this.onActive.bind(this)
  }

  onPresenceChange (presence) {
    // Handle state changes in one function
  }

  onPrompt () {
    // Fire a Modal Prompt
  }

  onIdle () {
    // Close Modal Prompt
    // Do some idle action like logging out your user
  }

  onActive (event) {
    // Close Modal Prompt
    // Do some active action
  }

  onAction (event) {
    // Do something when a user triggers a watched event
  }

  componentDidMount () {
    // IIdleTimer interface available on the reference to
    // the IdleTimer component instance
    this.idleTimer.start()
  }

  render () {
    return (
      <>
        <IdleTimer
          ref={ref => { this.idleTimer = ref }}
          timeout={1000 * 60 * 15}
          promptTimeout={1000 * 30}
          onPresenceChange={this.onPresenceChange}
          onPrompt={this.onPrompt}
          onIdle={this.onIdle}
          onAction={this.onAction}
          onActive={this.onActive}
          startManually
        />
        <HomePage />
      </>
    )
  }
}
```

### IdleTimer Injector

A better way would be to use the higher-order component to inject `IdleTimer` into your component. The event callbacks can be defined in your component scope and all the rest of the properties can be passed to your component.

Create the `IdleTimer` wrapped component.

```js
import { withIdleTimer, IdleTimerComponent } from 'react-idle-timer'

class AppComponent extends IdleTimerComponent {
  onPresenceChange (presence) {
    // Handle state changes in one function
  }
  
  onPrompt () {
    // Fire a Modal Prompt
  }

  onIdle () {
    // Close Modal Prompt
    // Do some idle action like logging out your user
  }

  onActive (event) {
    // Close Modal Prompt
    // Do some active action
  }

  onAction (event) {
    // Do something when a user triggers a watched event
  }

  componentDidMount () {
    // The IIdleTimer interface is supplied via props to your component
    this.props.start()
  }

  render () {
    return <HomePage />
  }
}

export const App = withIdleTimer(AppComponent)
```

Use the wrapped `IdleTimer` component.

```js
import { render } from 'react-dom'
import { App } from './App'

const element = document.getElementById('root')
render((
  <App 
    timeout={1000 * 60 * 15}
    promptTimeout={1000 * 30}
    startManually
  />
), element)
```

The wrapped component can also be instantiated deeper in the project hierarchy.
This would allow you to dynamically supply and update the [IIdleTimerProps](/docs/api/props)
interface to the `IdleTimer` instance.

```js
import { Component } from 'react'
import { App } from './App'

export class Root extends Component {
  constructor (props) {
    super(props)

    this.state = {
      timeout: 1000 * 60 * 15,
      promptTimeout: 1000 * 30
    }
  }

  render () {
    return (
      <App 
        timeout={this.state.timeout}
        promptTimeout={this.state.promptTimeout}
        startManually
      />
    )
  }
}

```

## Typescript

You can preserve your typescript types by utilizing the `withIdleTimer` generics.
Just make sure your props interface extends [IIdleTimer](/docs/api/types#IIdleTimer).

```tsx
import { Component, ReactNode } from 'react'
import { withIdleTimer, IdleTimerComponent, IIdleTimer } from 'react-idle-timer'

interface IAppProps extends IIdleTimer {
  foo: string
}

interface IAppState {
  bar: string
}

class AppComponent extends IdleTimerComponent<IAppProps, IAppState> {
  onPresenceChange (presence) {
    // Handle state changes in one function
  }
  
  onPrompt (): void {
    // Fire a Modal Prompt
  }

  onIdle (): void {
    // Close Modal Prompt
    // Do some idle action like logging out your user
  }

  onActive (event: Event): void {
    // Close Modal Prompt
    // Do some active action
  }

  onAction (event: Event): void {
    // Do something when a user triggers a watched event
  }

  componentDidMount (): void {
    // The IIdleTimer interface is supplied via props to your component
    this.props.start()
  }

  render (): ReactNode {
    return (
      <h1>{this.props.foo}</h1>
    )
  }
}

export const IdleTimer = withIdleTimer<IAppProps>(AppComponent)
```

Elsewhere in your app, render the typescript component. Your custom props will
be merged with the [IIdleTimer](/docs/api/methods) interface.

```tsx
import { Component, ReactNode } from 'react'
import { render } from 'react-dom'
import { App } from './App'

class Root extends Component<{}, {}> {
  render (): ReactNode {
    <App
      foo='bar'
      timeout={1000 * 60 * 15}
      promptTimeout={1000 * 30}
    />
  }
}

const element = document.getElementById('root')
render(<Root />, element)
```

## Examples

<Flex direction='column' mt={8}>
  <CodeSandboxButton name='higher-order-component-9fyvnr'>Higher Order Component</CodeSandboxButton>
</Flex>