React Native Cheatsheet
Native APIs
Use this React Native reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Alert
import { Alert } from 'react-native'; // Simple alert Alert.alert('Title', 'Message'); // With buttons Alert.alert( 'Delete Item', 'Are you sure?', [ { text: 'Cancel', style: 'cancel', onPress: () => {} }, { text: 'Delete', style: 'destructive', onPress: handleDelete }, ], { cancelable: true } // Android: dismiss on outside tap ); // Prompt (iOS only) Alert.prompt( 'Enter Name', 'Type your name below', (text) => console.log(text), 'plain-text', 'default value' );
Button style values
'default' | 'cancel' | 'destructive'
Linking — URLs & Deep Links
import { Linking } from 'react-native'; // Open URL await Linking.openURL('https://example.com'); await Linking.openURL('mailto:user@example.com'); await Linking.openURL('tel:+15551234567'); await Linking.openURL('sms:+15551234567'); // Check if URL can be opened const canOpen = await Linking.canOpenURL('myapp://home'); // Open app settings await Linking.openSettings(); // Handle deep links on app open const url = await Linking.getInitialURL(); if (url) handleDeepLink(url); // Listen while app is running const sub = Linking.addEventListener('url', ({ url }) => handleDeepLink(url)); return () => sub.remove();
Clipboard
npx expo install expo-clipboard
# or: npm install @react-native-clipboard/clipboardimport * as Clipboard from 'expo-clipboard'; // Copy await Clipboard.setStringAsync('Text to copy'); // Paste const text = await Clipboard.getStringAsync(); // Check if has string const has = await Clipboard.hasStringAsync(); // Image (Expo SDK 49+) await Clipboard.setImageAsync(base64String); const image = await Clipboard.getImageAsync({ format: 'png' });
Vibration
import { Vibration } from 'react-native'; Vibration.vibrate(); // single buzz Vibration.vibrate(500); // 500ms Vibration.vibrate([0, 500, 200, 500]); // pattern: wait, vibrate, wait, vibrate Vibration.vibrate([0, 500], true); // repeat pattern Vibration.cancel(); // stop repeating
Haptics (Expo)
npx expo install expo-haptics
import * as Haptics from 'expo-haptics'; Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium); Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Heavy); Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); Haptics.notificationAsync(Haptics.NotificationFeedbackType.Warning); Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error); Haptics.selectionAsync();
Camera
npx expo install expo-camera
import { CameraView, useCameraPermissions, CameraType } from 'expo-camera'; import { useRef, useState } from 'react'; function CameraScreen() { const [permission, requestPermission] = useCameraPermissions(); const cameraRef = useRef<CameraView>(null); const [facing, setFacing] = useState<CameraType>('back'); if (!permission?.granted) { return ( <View> <Text>Camera permission required</Text> <Pressable onPress={requestPermission}><Text>Grant</Text></Pressable> </View> ); } const takePicture = async () => { const photo = await cameraRef.current?.takePictureAsync({ quality: 0.8, base64: false, exif: false, }); console.log(photo?.uri); }; return ( <CameraView ref={cameraRef} style={{ flex: 1 }} facing={facing} flash="auto" // 'auto' | 'on' | 'off' > <Pressable onPress={takePicture} style={styles.capture} /> <Pressable onPress={() => setFacing(f => f === 'back' ? 'front' : 'back')}> <Text>Flip</Text> </Pressable> </CameraView> ); }
Image Picker
npx expo install expo-image-picker
import * as ImagePicker from 'expo-image-picker'; // Pick from gallery const result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ['images'], // 'images' | 'videos' | 'livePhotos' (MediaTypeOptions is deprecated) allowsEditing: true, aspect: [4, 3], quality: 0.8, allowsMultipleSelection: true, selectionLimit: 5, }); if (!result.canceled) { const { uri, width, height, fileSize, mimeType } = result.assets[0]; setImageUri(uri); } // Take photo with camera const photo = await ImagePicker.launchCameraAsync({ mediaTypes: ['images'], quality: 1, }); // Request permissions const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync(); const { status: cameraStatus } = await ImagePicker.requestCameraPermissionsAsync();
Location
npx expo install expo-location
import * as Location from 'expo-location'; // Request permission const { status } = await Location.requestForegroundPermissionsAsync(); if (status !== 'granted') return; // One-time location const location = await Location.getCurrentPositionAsync({ accuracy: Location.Accuracy.Balanced, // Accuracy: Lowest | Low | Balanced | High | Highest | BestForNavigation }); const { latitude, longitude, altitude, speed, heading } = location.coords; // Watch location const subscription = await Location.watchPositionAsync( { accuracy: Location.Accuracy.High, timeInterval: 5000, // min ms between updates distanceInterval: 10, // min meters between updates }, (location) => updateMap(location) ); // Cleanup subscription.remove(); // Reverse geocode const [place] = await Location.reverseGeocodeAsync({ latitude, longitude }); console.log(place.city, place.country, place.street); // Forward geocode const coords = await Location.geocodeAsync('1600 Amphitheatre Pkwy, Mountain View, CA');
Notifications (Push)
npx expo install expo-notifications
import * as Notifications from 'expo-notifications'; // Configure how notifications are shown Notifications.setNotificationHandler({ handleNotification: async () => ({ shouldShowBanner: true, // replaces deprecated shouldShowAlert (SDK 53+) shouldShowList: true, // show in the notification center list shouldPlaySound: true, shouldSetBadge: false, }), }); // Request permission + get Expo push token const { status } = await Notifications.requestPermissionsAsync(); const token = (await Notifications.getExpoPushTokenAsync({ projectId: 'your-project-id' })).data; // Send `token` to your server to store for push notifications // Schedule local notification await Notifications.scheduleNotificationAsync({ content: { title: 'Reminder', body: 'Time to check in!', data: { screen: 'Home' }, badge: 1, }, trigger: { type: Notifications.SchedulableTriggerInputTypes.TIME_INTERVAL, seconds: 60, repeats: false, }, // triggers require an explicit `type` in current SDKs }); // Daily notification at specific time await Notifications.scheduleNotificationAsync({ content: { title: 'Daily', body: 'Good morning!' }, trigger: { type: Notifications.SchedulableTriggerInputTypes.DAILY, hour: 8, minute: 0, }, }); // Cancel all scheduled await Notifications.cancelAllScheduledNotificationsAsync(); // Badge await Notifications.setBadgeCountAsync(5); await Notifications.setBadgeCountAsync(0); // clear // Listeners const sub1 = Notifications.addNotificationReceivedListener(notification => { console.log(notification.request.content); }); const sub2 = Notifications.addNotificationResponseReceivedListener(response => { const data = response.notification.request.content.data; navigation.navigate(data.screen); }); return () => { sub1.remove(); sub2.remove(); };
AppState
import { AppState } from 'react-native'; console.log(AppState.currentState); // 'active' | 'background' | 'inactive' (iOS) const sub = AppState.addEventListener('change', nextAppState => { if (nextAppState === 'active') { // App came to foreground — refresh data, restart timers } if (nextAppState === 'background') { // App went to background — save state, pause timers } }); return () => sub.remove();
Permissions
import { PermissionsAndroid, Platform } from 'react-native'; // Android manual permissions (API < 33) if (Platform.OS === 'android') { const granted = await PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.CAMERA, { title: 'Camera Permission', message: 'App needs camera access', buttonPositive: 'OK', buttonNegative: 'Cancel', } ); if (granted === PermissionsAndroid.RESULTS.GRANTED) { openCamera(); } } // Expo unified API import { Camera } from 'expo-camera'; const { status } = await Camera.requestCameraPermissionsAsync(); // status: 'granted' | 'denied' | 'undetermined'
Secure Auth Token Pattern (expo-secure-store)
// lib/auth.ts — Keychain (iOS) / Keystore (Android) backed storage // npx expo install expo-secure-store import * as SecureStore from 'expo-secure-store'; export const AUTH_KEY = 'auth_token'; export async function saveToken(token: string) { await SecureStore.setItemAsync(AUTH_KEY, token); } export async function getToken(): Promise<string | null> { return SecureStore.getItemAsync(AUTH_KEY); } export async function deleteToken() { await SecureStore.deleteItemAsync(AUTH_KEY); } // In app startup useEffect(() => { getToken().then(token => { if (token) dispatch({ type: 'RESTORE_TOKEN', token }); else dispatch({ type: 'SIGN_OUT' }); }); }, []);
Sensors (Expo)
npx expo install expo-sensors
import { Accelerometer, Gyroscope, DeviceMotion } from 'expo-sensors'; // Accelerometer Accelerometer.setUpdateInterval(100); // ms const sub = Accelerometer.addListener(({ x, y, z }) => { console.log(x, y, z); }); sub.remove(); // Device orientation const available = await DeviceMotion.isAvailableAsync(); DeviceMotion.setUpdateInterval(200); const sub = DeviceMotion.addListener(({ rotation, acceleration }) => { const { alpha, beta, gamma } = rotation; // radians });