Skip to main content

Managing App Lifecycle

1. Handling App State Changes

State Description Usage
active App is in the foreground and visible to the user. Use for resuming operations, updating UI, starting timers.
background App is in the background but still running. Use for pausing operations, stopping timers, saving state.
inactive App is in the background but not actively running. Use for cleaning up resources or preparing for suspension.

Example: Listening to App State Changes

import { AppState } from 'react-native';

const handleAppStateChange = (nextAppState) => {
  if (nextAppState === 'active') {
    console.log('App has come to the foreground!');
  } else if (nextAppState === 'background') {
    console.log('App has gone to the background!');
  }
};

AppState.addEventListener('change', handleAppStateChange);

// Don't forget to remove the listener when component unmounts
// AppState.removeEventListener('change', handleAppStateChange);
Note: On iOS, the inactive state is not emitted. On Android, it might be emitted in some edge cases.
Warning: Do not rely on AppState for critical app logic as it can be unreliable in some edge cases or device-specific scenarios.

2. Using AppState Events

Event Name Description Notes
appState Triggered when the app state changes (e.g., foreground, background) Useful for managing resources and user experience
appStateChange Event fired when the app transitions between states Can be used to pause or resume operations

Example: Listening to AppState Changes

import { AppState } from 'react-native';

const handleAppStateChange = (nextAppState) => {
  if (nextAppState === 'active') {
    console.log('App is active');
  } else if (nextAppState === 'background') {
    console.log('App is in background');
  } else if (nextAppState === 'inactive') {
    console.log('App is inactive');
  }
};

AppState.addEventListener('change', handleAppStateChange);

// Clean up listener
const unsubscribe = () => AppState.removeEventListener('change', handleAppStateChange);
Note: The appState event is not supported on all platforms. On iOS, it may not fire in the background.

3. Detecting App Launch

Method Description Notes
AppState Monitors the state of the app (active, background, inactive) Useful for managing resources and UI updates
useAppState React hook to access AppState in functional components Provides real-time updates on app state changes

Example: Using AppState to detect app launch

import { AppState } from 'react-native';\n\nconst handleAppStateChange = (nextAppState) => {\n  if (nextAppState === 'active') {\n    console.log('App has come to foreground');\n  }\n};\n\nAppState.addEventListener('change', handleAppStateChange);\n\n// Cleanup listener when component unmounts\nreturn () => {\n  AppState.removeEventListener('change', handleAppStateChange);\n};

Example: Using useAppState hook

import { useAppState } from 'react-native';\n\nconst App = () => {\n  const appState = useAppState();\n\n  useEffect(() => {\n    if (appState === 'active') {\n      console.log('App launched or resumed');\n    }\n  }, [appState]);\n\n  return <View></View>;\n};
Note: AppState changes can occur due to various reasons like app switching, device lock, or push notifications. Always handle these transitions gracefully.

4. Handling App Close

Event Description Usage
appState Indicates the state of the app (active, background, inactive) AppState.addEventListener('change', (newState) => { ... });

Example: Detecting App Close

import { AppState } from 'react-native';

const handleAppStateChange = (nextAppState) => {
  if (nextAppState === 'background') {
    console.log('App went to background');
  } else if (nextAppState === 'active') {
    console.log('App came to foreground');
  }
};

AppState.addEventListener('change', handleAppStateChange);

// Clean up listener
const removeListener = () => {
  AppState.removeEventListener('change', handleAppStateChange);
};
Note: On iOS, when the app is closed, appState will be 'inactive' and then 'background'. On Android, it will go directly to 'background'.

5. Using Splash Screen

The splash screen is the first thing users see when they open your app. It's crucial for branding and providing a smooth transition from app launch to the main interface.

Property Description Default Value Notes
splash.image Path to the splash screen image file assets/splash.png Must be a PNG or JPG file. Recommended size: 1024x1024px
splash.resizeMode How the image should be resized to fit the screen contain Options: cover, contain, stretch
splash.backgroundColor Background color of the splash screen #ffffff Can be any valid CSS color value
splash.showWhenLocked Whether to show the splash screen while the app is locked true Only affects iOS devices

Example: Configuring Splash Screen in app.json

{
  "expo": {
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    }
  }
}
Note: The splash screen is only shown during the app's initial load. Once your app's main component mounts, the splash screen is dismissed automatically.
Warning: If you're using a custom splash screen, make sure to set the backgroundColor to match your image's background color to prevent any visual artifacts.

Key Points

  • Splash screen is shown during app launch
  • Can be customized with image, background color, and resize mode
  • Image should be at least 1024x1024px for optimal display
  • Use backgroundColor to match your image's background

6. Hiding Splash Screen

After the splash screen is shown, it can be hidden programmatically to reveal the app content.

Method Description Notes
SplashScreen.hideAsync() Hides the splash screen asynchronously Must be called after the app is ready to display content

Example: Hiding Splash Screen

import * as SplashScreen from 'expo-splash-screen';

// Hide splash screen after app is ready
SplashScreen.hideAsync();
Note: Ensure that the splash screen is hidden only after all necessary resources are loaded to prevent flickering or premature content display.

7. Preventing Auto Hide

Expo's auto-hide behavior can be controlled to prevent the status bar and navigation bar from automatically hiding on Android devices.

Property Values Description
androidStatusBar.hidden true / false When set to true, the status bar is hidden. Defaults to false.
androidStatusBar.translucent true / false If set to true, the status bar is translucent. Defaults to false.
androidStatusBar.backgroundColor Hex color code Background color of the status bar. Example: #000000.

Example: Preventing Auto Hide in Android

{
  "expo": {
    "androidStatusBar": {
      "hidden": true,
      "translucent": false,
      "backgroundColor": "#000000"
    }
  }
}
Note: On Android, the status bar can be hidden using StatusBar API from expo-status-bar package. The configuration in app.json is a global setting and affects all screens.
Warning: Hiding the status bar might affect accessibility and usability on some devices. Ensure that your app provides alternative ways to access important controls or information.
Property Description Example
useDeepLink Hook to handle deep links in Expo apps const { scheme } = useDeepLink();
getInitialURL Get the URL that launched the app const url = await Linking.getInitialURL();
addEventListener Listen for deep link events Linking.addEventListener('url', handleUrl);
import { Linking } from 'expo';\n\nconst handleUrl = (event) => {\n  const { url } = event;\n  console.log('Deep link received:', url);\n};\n\nLinking.addEventListener('url', handleUrl);\n\n// Get initial URL if app was opened via deep link\nLinking.getInitialURL().then((url) => {\n  if (url) {\n    console.log('Initial URL:', url);\n  }\n});
Note: Deep links must be configured in your app's app.json or app.config.js under the scheme property to work correctly.
  • Add scheme to your app config for custom URL schemes
  • Use Linking.getInitialURL() to retrieve the URL that launched the app
  • Use Linking.addEventListener('url', handler) to listen for deep link events

9. Managing Memory Warnings (iOS)

Property Description Notes
onMemoryWarning Callback function triggered when iOS memory warning is received Only available on iOS

Example: Handling Memory Warnings

import { AppState } from 'react-native';<br><br>const handleMemoryWarning = () => {<br>  console.warn('Memory warning received');<br>  // Perform cleanup tasks here<br>};<br><br>AppState.addEventListener('memoryWarning', handleMemoryWarning);
Note: Memory warnings are not guaranteed to be sent, but they can occur when the system is under memory pressure.

10. Handling Background Fetch

Property Description Values
BackgroundFetch Enables background fetch capabilities true or false
BackgroundFetchInterval Time interval between fetches in milliseconds 30000 (30 seconds)

Example: Configure Background Fetch

import * as BackgroundFetch from 'expo-background-fetch';

const backgroundFetchTask = async () => {
  console.log('Background fetch task executed');
  // Perform data sync or other operations
};

BackgroundFetch.registerTaskAsync('my-task', {
  stopOnTerminate: false,
  startOnBoot: true,
  periodic: true,
  interval: 30000,
});

BackgroundFetch.startTaskAsync('my-task');
Note: Background fetch is subject to OS-level limitations and may not execute at exact intervals.

Was this article helpful?