All Posts

useUpdates() API for expo-updates

Aug 8, 2023 by

Avatar of Doug Lowder

Doug Lowder

An app showing that a new update is available

The expo-updates module allows your app to download and manage remote updates to your application code.

We now provide a React hook, useUpdates(), for hooking into state and lifecycle updates from the module. The new hook makes use of a new state machine implemented within the native code.

Features:

  • Wraps information on the currently running app bundle, and any available or downloaded new updates
  • Reads from and receives change events from the native state machine, so it always reflects the current state of the system
  • Can be used from any component in the application
  • Tracks the last time the device checked the update server for an available update
  • Existing async methods (checkForUpdateAsync(), fetchUpdateAsync()) can be called without waiting for results -- the hook will automatically refresh when the methods complete
  • Surfaces errors that occur during initialization, checking for update, or downloading an update

The useUpdates() hook is currently in alpha and will be stable in SDK 50.

Example app

We have created the Updates API Demo app as a working example of an app that uses the new API.

Example usage

import { StatusBar } from 'expo-status-bar';
import * as Updates from 'expo-updates';
import React from 'react';
import { Text, View } from 'react-native';

export default function UpdatesDemo() {
  const {
    currentlyRunning,
    isUpdateAvailable,
    isUpdatePending
  } = Updates.useUpdates();

  // If true, we show the button to download and run the update
  const showDownloadButton = isUpdateAvailable;

  React.useEffect(() => {
    if (isUpdatePending) {
      // Update has been successfully downloaded,
      // so reload with the new update bundle
      Updates.reloadAsync();
    }
  }, [isUpdatePending]);

  // Show whether or not we are running embedded code or an update
  const runTypeMessage = currentlyRunning.isEmbeddedLaunch
    ? 'This app is running from built-in code'
    : 'This app is running an update';

  return (
    <View style={styles.container}>
      <Text style={styles.headerText}>Updates Demo</Text>
      <Text>{runTypeMessage}</Text>
      <Button
        pressHandler={() => Updates.checkForUpdateAsync()}
        text="Check manually for updates"
      />
      {showDownloadButton && (
        <Button
          pressHandler={() => Updates.fetchUpdateAsync()}
          text="Download and run update"
        />
      )}
      <StatusBar style="auto" />
    </View>
  );
}

Credits

Avatar of Doug Lowder

Doug Lowder as project lead

Avatar of Quinlan Jung

Quinlan Jung as a contributor

Avatar of Will Schurman

Will Schurman as a contributor

Avatar of Jon Samp

Jon Samp as a tester