The useUpdates
Hook is a new React Hook provided by the Expo team that enables developers to seamlessly manage updates with the expo-updates
library.
This Hook is an important advancement in managing updates within React Native applications that helps streamline the application update process and improve the overall user experience. In this article, we will explore:
useUpdates
Hook mattersexpo-updates
works with useUpdates
useUpdates
HookuseUpdates
in actionWe’ll see a simple example of the useUpdates
Hook later in this article. You can check out the code for this example on GitHub.
useUpdates
Hook mattersManaging updates in React Native applications often requires manual implementations and complex handling of various components. Developers may need to devise and implement custom strategies to check and integrate updates, leading to complex and error-prone procedures.
These methods also usually lack standardization and can vary significantly depending on the application’s requirements and specifics. A solution to the problems and challenges of the update management process was sorely needed.
Although still in alpha, that’s where the useUpdates
Hook steps in. It significantly reduces the burden on developers, allowing them to focus more on development and improving the user experience.
The useUpdates
Hook helps streamline the update management process, providing a simplified and standardized approach to handling updates seamlessly. It automates tasks such as downloads, integrations, and update checks, and provides many features that directly address the challenges of managing updates in React Native applications.
An example use case where the useUpdates
Hook will provide significant value is in large-scale applications where real-time updates and stability are critical. The useUpdates
Hook ensures that users always have access to the latest features and improvements, providing a more seamless and engaging application experience.
expo-updates
works with useUpdates
expo-updates
is an Expo SDK library that lets you control application behavior programmatically based on new updates made to the app. Basically, this library allows your app to download and manage remote updates.
The useUpdates
Hook serves as an interface for capturing and responding to state and lifecycle updates originating from the module. It’s powered by a newly implemented state machine embedded within the native code that enables you to manage changes in a more streamlined and efficient way.
useUpdates
HookThe useUpdates
Hook provides a handful of features that can help improve the way you manage updates in your React Native applications. Let’s take a look at some of these features.
The useUpdates
Hook provides encapsulated information regarding the current running app bundle, along with any newly available or downloaded updates. This easy access to essential details about the application’s current state and any pending updates simplifies the process of managing updates to the app.
As mentioned earlier, the Hook utilizes a newly implemented state machine within the native code. This integration ensures that the useUpdates
Hook remains synchronized with any ongoing state changes and consistently reflects the most up-to-date information from the system.
You can access the useUpdates
Hook from any component within your React Native application. This flexibility allows different components to leverage the capabilities of this Hook without limitations.
With the useUpdates
Hook, you can now track when a device last checked the update server for any available updates. This feature helps keep your application up-to-date with the latest changes without repeating checks unnecessarily, which helps optimize performance.
The useUpdates
Hook supports existing asynchronous methods like checkForUpdatesAsync()
and fetchUpdateAsync()
. It automatically refreshes once these methods complete, removing the need for explicit await
statements and providing a seamless user experience during the update process.
The useUpdates
Hook surfaces any errors that occur during the initialization process, while checking for updates, or when downloading an update. This feature helps developers identify and resolve issues in their React Native apps quickly, ensuring smooth and error-free update management within applications.
useUpdates
in actionLet’s demonstrate how to use the useUpdates
Hook to update an application.
In the code below, we’ll use the useUpdates
Hook from the expo-updates
dependency. Then, we’ll destructure three different methods from this Hook to allow us achieve our app update goal:
currentlyRunning:
Holds information about the currently running app bundle. This method helps you track the version that the application is currently using, which is useful for managing and understanding the state of the application in real-time
isUpdateAvailable
: A Boolean value indicating whether an update is available for the application. It helps you determine whether a new version of the application is ready for download and integration
isUpdatePending
: Another Boolean value that indicates whether an update is currently pending for the application. It helps you track whether an update has been downloaded and is awaiting integration or reloadNote that in addition to the methods that we’re using in our example, the useUpdates
Hook offers three other methods:
isChecking
: A Boolean method that indicates whether the system is currently checking for any available updates. It offers insight as to whether an update check is in progress, which helps keep your application relevant and secure by ensuring that it stays up-to-dateisDownloading
: Indicates whether the application is currently downloading an available update. It allows both developers and users to track the update download progress, providing transparency and clarity on the current status of the application’s update processlastCheckForUpdateTimeSinceRestart
: Stores the timestamp of when the device last checked for any available updates since its most recent restart. It serves as a reference point for understanding when your application last searched for updates, which helps prevent unnecessarily frequent checks and optimize the update processHere’s the code for our example:
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 Demo() { const { currentlyRunning, isUpdateAvailable, isUpdatePending } = Updates.useUpdates();
Next, let’s provide a way for users to download and run updates:
const showDownloadButton = isUpdateAvailable; React.useEffect(() => { if (isUpdatePending) { Updates.reloadAsync(); } }, [isUpdatePending]);
If the isUpdateAvailable
method returns true
, we assign this value to the showDownloadButton
variable to display a button on the user interface. The user can press this button to download and run the updates.
Then, we use the useEffect
Hook to check if the application has any pending updates. If there are any pending updates, we call the reloadAsync()
method to reload the app with the new update bundle.
In the useEffect
dependency array, the isUpdatePending
method is passed in as an argument. This means the useEffect
Hook only runs when the value of isUpdatePending
changes, whether the value is true
or false
.
Next, we’ll create a variable called runTypeMesage
:
const runTypeMessage = currentlyRunning.isEmbeddedLaunch ? 'This app is running from built-in code' : 'This app is running an update';
We assign a value to this variable based on the value of the isEmbeddedLaunch
property of the currentlyRunning
object.
If the isEmbeddedLaunch
property is true, the message assigned to runTypeMessage
will be: This app is running from built-in code. This message means that the application is currently running from its original, built-in code without any updates applied.
On the other hand, if the isEmbeddedLaunch
property is false
, the message assigned to runTypeMessage
will be: This app is running an update.
This in turn, means that the application is currently running with an applied update, not from the built-in code. In other words, the code has been updated since the original built-in version.
Finally, we need to write our return
statement:
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> ); }
In our return
statement, we set up two buttons triggering two methods:
checkForUpdateAsync
method manually checks the server to see if a newly deployed update to a project is availablefetchUpdateAsync
method downloads the most recently deployed update to a project from the server to the device’s local storage.You can check out the code for this example here.
In this tutorial, we explored the useUpdates
Hook and how you can use it alongside Expo to get updates from components in your application. You can also check for updates as well as errors at any stage of an update.
Remember, the useUpdates
Hook is still currently in alpha. It will be stable and ready for proper usage when Expo SDK 50 is released.
LogRocket is a React Native monitoring solution that helps you reproduce issues instantly, prioritize bugs, and understand performance in your React Native apps.
LogRocket also helps you increase conversion rates and product usage by showing you exactly how users are interacting with your app. LogRocket's product analytics features surface the reasons why users don't complete a particular flow or don't adopt a new feature.
Start proactively monitoring your React Native apps — try LogRocket for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowCompare Prisma and Drizzle ORMs to learn their differences, strengths, and weaknesses for data access and migrations.
It’s easy for devs to default to JavaScript to fix every problem. Let’s use the RoLP to find simpler alternatives with HTML and CSS.
Learn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
Bypass anti-bot measures in Node.js with curl-impersonate. Learn how it mimics browsers to overcome bot detection for web scraping.