1import { useEffect, useState } from 'react'; 2 3import { getNativeStateMachineContextAsync } from './Updates'; 4import { addUpdatesStateChangeListener } from './UpdatesEmitter'; 5import type { UseUpdatesReturnType } from './UseUpdates.types'; 6import { 7 currentlyRunning, 8 defaultUseUpdatesState, 9 reduceUpdatesStateFromContext, 10} from './UseUpdatesUtils'; 11import type { UseUpdatesStateType } from './UseUpdatesUtils'; 12 13/** 14 * Hook that obtains information on available updates and on the currently running update. 15 * 16 * @return the structures with information on currently running and available updates. 17 * 18 * @example 19 * ```tsx UpdatesDemo.tsx 20 * import { StatusBar } from 'expo-status-bar'; 21 * import * as Updates from 'expo-updates'; 22 * import React from 'react'; 23 * import { Pressable, Text, View } from 'react-native'; 24 * 25 * export default function UpdatesDemo() { 26 * const { 27 * currentlyRunning, 28 * availableUpdate, 29 * isUpdateAvailable, 30 * isUpdatePending 31 * } = Updates.useUpdates(); 32 * 33 * React.useEffect(() => { 34 * if (isUpdatePending) { 35 * // Update has successfully downloaded 36 * runUpdate(); 37 * } 38 * }, [isUpdatePending]); 39 * 40 * // If true, we show the button to download and run the update 41 * const showDownloadButton = isUpdateAvailable; 42 * 43 * // Show whether or not we are running embedded code or an update 44 * const runTypeMessage = currentlyRunning.isEmbeddedLaunch 45 * ? 'This app is running from built-in code' 46 * : 'This app is running an update'; 47 * 48 * return ( 49 * <View style={styles.container}> 50 * <Text style={styles.headerText}>Updates Demo</Text> 51 * <Text>{runTypeMessage}</Text> 52 * <Button pressHandler={() => Updates.checkForUpdateAsync()} text="Check manually for updates" /> 53 * {showDownloadButton ? ( 54 * <Button pressHandler={() => Updates.fetchUpdateAsync()} text="Download and run update" /> 55 * ) : null} 56 * <StatusBar style="auto" /> 57 * </View> 58 * ); 59 * } 60 * ``` 61 */ 62export const useUpdates: () => UseUpdatesReturnType = () => { 63 const [updatesState, setUpdatesState] = useState<UseUpdatesStateType>(defaultUseUpdatesState); 64 65 // Change the state based on native state machine context changes 66 useEffect(() => { 67 getNativeStateMachineContextAsync().then((context) => { 68 setUpdatesState((updatesState) => reduceUpdatesStateFromContext(updatesState, context)); 69 }); 70 const subscription = addUpdatesStateChangeListener((event) => { 71 setUpdatesState((updatesState) => reduceUpdatesStateFromContext(updatesState, event.context)); 72 }); 73 return () => subscription.remove(); 74 }, []); 75 76 // Return the updates info and the user facing functions 77 return { 78 currentlyRunning, 79 ...updatesState, 80 }; 81}; 82