┌─────────────────────────────┐ │ Camera Screen │ ├─────────────────────────────┤ │ [Camera preview area] │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ [Snap Button] │ └─────────────────────────────┘
Camera access (expo-camera) in React Native - Mini App: Build & Ship
import React, { useState, useEffect, useRef } from 'react'; import { View, Text, Button, Image, StyleSheet } from 'react-native'; import { Camera } from 'expo-camera'; export default function CameraScreen() { const [hasPermission, setHasPermission] = useState(null); const [photoUri, setPhotoUri] = useState(null); const cameraRef = useRef(null); useEffect(() => { (async () => { // TODO: Request camera permission here })(); }, []); const takePicture = async () => { // TODO: Take picture and save uri }; return ( <View style={styles.container}> {/* TODO: Show camera preview or permission message here */} {/* TODO: Snap button here */} {/* TODO: Show taken photo here */} </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center' }, camera: { width: 300, height: 400 }, photo: { width: 300, height: 400, marginTop: 10 } });
import React, { useState, useEffect, useRef } from 'react'; import { View, Text, Button, Image, StyleSheet } from 'react-native'; import { Camera } from 'expo-camera'; export default function CameraScreen() { const [hasPermission, setHasPermission] = useState(null); const [photoUri, setPhotoUri] = useState(null); const cameraRef = useRef(null); useEffect(() => { (async () => { const { status } = await Camera.requestCameraPermissionsAsync(); setHasPermission(status === 'granted'); })(); }, []); const takePicture = async () => { if (cameraRef.current) { const photo = await cameraRef.current.takePictureAsync(); setPhotoUri(photo.uri); } }; if (hasPermission === null) { return <View style={styles.container}><Text>Requesting camera permission...</Text></View>; } if (hasPermission === false) { return <View style={styles.container}><Text>No access to camera</Text></View>; } return ( <View style={styles.container}> <Camera style={styles.camera} ref={cameraRef} /> <Button title="Snap" onPress={takePicture} /> {photoUri && <Image source={{ uri: photoUri }} style={styles.photo} />} </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center' }, camera: { width: 300, height: 400 }, photo: { width: 300, height: 400, marginTop: 10 } });
This solution first asks the user for camera permission when the screen loads using Camera.requestCameraPermissionsAsync(). The permission status is saved in state.
If permission is granted, the camera preview is shown using the Camera component from expo-camera. We keep a reference to the camera with useRef so we can call takePictureAsync() when the user presses the 'Snap' button.
When the button is pressed, the app takes a photo and saves its URI in state. Then the photo is displayed below the button using an Image component.
If permission is denied, a simple message 'No access to camera' is shown instead.
This approach keeps the UI simple and clear, and handles permission states properly.
┌─────────────────────────────┐ │ Camera Screen │ ├─────────────────────────────┤ │ [Camera preview area] │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ [Snap Button] │ │ │ │ [Photo preview after snap] │ └─────────────────────────────┘
Practice
expo-camera?Solution
Step 1: Understand permission requirement
Mobile apps must ask user permission before accessing hardware like the camera.Step 2: Request camera permission first
Usingexpo-camera, you call permission request functions before showing the camera.Final Answer:
Request permission to access the camera -> Option BQuick Check:
Permission request = A [OK]
- Trying to show camera preview without permission
- Taking picture before permission granted
- Skipping permission request step
expo-camera?Solution
Step 1: Check expo-camera export style
The Camera component is a named export, so it must be imported with curly braces.Step 2: Use correct import syntax
Correct syntax isimport { Camera } from 'expo-camera';to access the Camera component.Final Answer:
import { Camera } from 'expo-camera'; -> Option DQuick Check:
Named import uses curly braces = D [OK]
- Using default import without braces
- Importing everything as an object
- Using wrong import names
expo-camera?
const [hasPermission, setHasPermission] = React.useState(null);
React.useEffect(() => {
(async () => {
const { status } = await Camera.requestCameraPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
return hasPermission === null ? Requesting permission : hasPermission === false ? No access : ;Solution
Step 1: Analyze permission state flow
Initially,hasPermissionis null, so it shows 'Requesting permission'.Step 2: After permission request
If permission granted,hasPermissionbecomes true and camera preview shows; if denied, shows 'No access'.Final Answer:
Shows 'Requesting permission' text initially, then camera preview if granted -> Option CQuick Check:
Permission null -> text, granted -> camera = B [OK]
- Expecting camera preview before permission granted
- Confusing permission states
- Ignoring async permission request
expo-camera:
const cameraRef = React.useRef(null);
async function takePicture() {
if (cameraRef) {
const photo = await cameraRef.current.takePictureAsync();
console.log(photo.uri);
}
}Solution
Step 1: Check cameraRef usage
cameraRef is a ref object; to access the camera instance, usecameraRef.current.Step 2: Correct condition check
The condition should checkif (cameraRef.current)to ensure the camera is ready.Final Answer:
cameraRef should be checked as cameraRef.current, not cameraRef -> Option AQuick Check:
Ref object needs .current to access value = C [OK]
- Checking ref object directly instead of .current
- Forgetting async on takePictureAsync
- Misusing console.log for URIs
Solution
Step 1: Request permission before camera use
Always ask and confirm permission before showing camera preview.Step 2: Show camera preview and take picture
Use a ref to access the camera and take a picture only after permission granted.Step 3: Save photo URI in state
Store the photo URI in state to use or display later in the app.Final Answer:
Request permission -> Show camera preview -> Use ref to take picture -> Save URI in state -> Option AQuick Check:
Permission first, then camera, then save = A [OK]
- Taking picture before permission
- Saving URI before picture taken
- Showing camera without permission
Ready to prove it?
Pass the test and this pattern moves unknown
