Managing User Inactivity and Logout in React Native with MobX

Emmanuel Ututu
4 min readJan 5, 2025

--

Photo by MK Hamilton on Unsplash

Managing user inactivity is crucial in applications that deal with sensitive information or require session-based authentication. It ensures better security by logging users out after a period of inactivity and improves user experience by maintaining clear session boundaries. In this tutorial, we will explore how to implement a robust inactivity handler in a React Native app using MobX.

Prerequisites

  1. Familiarity with React Native and basic concepts of hooks and state management.
  2. Basic understanding of MobX for state management.

Step 1: Install Necessary Dependencies

Before we dive into the code, make sure you have the following dependencies installed in your project:

npm install mobx mobx-react-lite @react-navigation/native 

Step 2: Create the Account Store

Photo by Manny Becerra on Unsplash

MobX makes state management straightforward and reactive. We’ll create a store to manage our inactivity timer.

Create a file namedaccountStore.ts (you can use any name you prefer) in your stores directory.

import {makeAutoObservable, runInAction} from 'mobx';
import {Alert} from 'react-native';

class AccountStore {
// Timer reference to manage inactivity timeout
inactivityTimeout: ReturnType<typeof setTimeout> | null = null;

// Duration after which the user is considered inactive (5 minutes)
inactivityDuration = 300000;

// Callback to execute when inactivity is detected
onInactivityCallback: (() => void) | null = null;

constructor() {
// Automatically makes properties observable and actions bindable
makeAutoObservable(this);
}

// Starts the inactivity timer with the provided callback
startInactivityTimer(callback: () => void) {
// Prevents starting a new timer if one is already active
if (this.inactivityTimeout !== null) {
return;
}

this.onInactivityCallback = callback;

// Sets a timeout to trigger inactivity behavior after the specified duration
this.inactivityTimeout = setTimeout(() => {
if (this.onInactivityCallback) {
this.onInactivityCallback(); // Executes the provided callback

// Alerts the user about session timeout
Alert.alert('Info', 'Your session has timed out, please login again.');
}
this.clearInactivityTimer(); // Clears the timer to reset its state
}, this.inactivityDuration);
}

// Resets the inactivity timer, extending the session
resetInactivityTimer() {
// Ensures the timer is active before resetting
if (this.inactivityTimeout !== null) {
this.clearInactivityTimer(); // Clears the existing timer
this.startInactivityTimer(this.onInactivityCallback!); // Restarts the timer
}
}

// Clears the inactivity timer to release resources and reset state
clearInactivityTimer() {
if (this.inactivityTimeout !== null) {
clearTimeout(this.inactivityTimeout); // Clears the timeout
this.inactivityTimeout = null; // Resets the timer reference
}
}
}

// Exports a singleton instance of the store for global use
export default new AccountStore();

Step 3: Create the Hook

React Native’s hooks allow us to efficiently manage component lifecycles. We’ll create a custom hook to handle inactivity using the useFocusEffect hook from @react-navigation/native.

Create a file named useInactivityTimer.ts (again, you can give the file a name of your choice) in your hooks directory.

import {useCallback} from 'react';
import {useFocusEffect} from '@react-navigation/native';
import accountStore from '../stores/accountStore';

type UseInactivityTimerProps = {
navigation: any;
timeoutCallback: () => void;
};

export const useInactivityTimer = ({
navigation,
timeoutCallback,
}: UseInactivityTimerProps) => {
useFocusEffect(
useCallback(() => {
accountStore.startInactivityTimer(timeoutCallback);

return () => {
accountStore.clearInactivityTimer();
};
}, [navigation, timeoutCallback]),
);

const resetInactivityTimer = useCallback(() => {
accountStore.resetInactivityTimer();
}, []);

return {
resetInactivityTimer,
};
};

Step 4: Implement the Hook in a Screen

Now, let’s implement the inactivity handler in one of our screens. We’ll use the useInactivityTimer hook to start the timer when the screen is in focus and reset it based on user interactions. This approach can also be used across different screens in your project since it’s a hook.

import React from 'react';
import {View, Text} from 'react-native';
import {useInactivityTimer} from '../hooks/useInactivityTimer';
import Container from '../components/Container';
import styles from '../styles';

const HomeScreen = ({navigation}: {navigation: any}) => {
const {resetInactivityTimer} = useInactivityTimer({
navigation,
timeoutCallback: () => {
navigation.reset({
index: 0,
routes: [{name: 'login'}],
});
},
});

return (
<Container
scroll
style={styles.container}
onTouchStart={resetInactivityTimer}>
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text>Welcome to the Home Screen</Text>
</View>
</Container>
);
};

export default HomeScreen;

Step 5: Testing the Inactivity Timer

To test the inactivity timer:

  1. Run your application.
  2. Navigate to the HomeScreen.
  3. Wait for 5 minutes without interacting with the app to see the timeout behaviour.
  4. Interact with the app and ensure the timer resets on every interaction.

Step 6: Why These Features?

  1. MobX: Provides a simple and reactive state management solution, making it ideal for managing the inactivity timer.
  2. useFocusEffect: Ensures the timer starts only when the screen is in focus, preventing unnecessary timers.
  3. onTouchStart** Prop**: A React Native prop used to detect any touch activity, such as scrolling, tapping, or swiping, within the component. It ensures that the inactivity timer resets whenever the user interacts with the screen.
  4. Custom Hook: Encapsulates the inactivity logic into a reusable function, keeping the codebase clean and modular.

Conclusion

Inactivity management is essential for building secure and user-friendly applications. In this tutorial, we have demonstrated how to use MobX and React Native hooks to implement a flexible and reusable inactivity handler. By encapsulating the logic into a custom hook and leveraging the onTouchStart prop for comprehensive interaction detection, we achieved a robust and efficient solution. Feel free to extend this implementation to suit your app’s specific requirements and deliver a seamless user experience.

Cheers to more coding 🥂.

--

--

Emmanuel Ututu
Emmanuel Ututu

Written by Emmanuel Ututu

Passionate mobile developer & writer, with several years of experience, adding creativity & imagination to projects. I love to dream of needs and their solution

No responses yet