my space

Detect user idle in react-native

react-native

June 26, 2020

One of the requirement in an app with sensitive data is to force user to logout if the user has been idle for certain amount of time. By idle, I mean the user doesn’t touch anything in the app. Normally, we use Touchable* to detect a user press event. But we cannot apply this on top of another element because it will override all touch event on the pages and your app won’t be functional. After a brief research, I found that we can use PanResponder.

My strategy is to apply PanResponser on top of the app. We start a setTimeout with a certain amount of time (supposed to be configurable) during the user opens the app. Whenever the user presses anywhere on the screen, we clearTimeout and reset it. Note that I used onStartShouldSetPanResponderCapture of PanResponser event to detect user touch event.

import React, { useState, useEffect, useRef } from "react"
import { View, PanResponder } from "react-native"

const AppContainer = props => {
  const timerId = useRef(false)
  const [timeForInactivityInSecond, setTimeForInactivityInSecond] = useState(
    3600
  )

  useEffect(() => {
    resetInactivityTimeout()
  }, [])

  const panResponder = React.useRef(
    PanResponder.create({
      onStartShouldSetPanResponderCapture: () => {
        // console.log('user starts touch');
        resetInactivityTimeout()
      },
    })
  ).current

  const resetInactivityTimeout = () => {
    clearTimeout(timerId.current)
    timerId.current = setTimeout(() => {
      // action after user has been detected idle
    }, timeForInactivityInSecond * 1000)
  }

  return (
    <View style={{ flex: 1 }} {...panResponder.panHandlers}>
      {/* <YourApp {...props} /> */}
    </View>
  )
}

export default AppContainer

gie

Written by gie who lives and works in Bangkok. Build things by code.
my twitter | github