0
0
React Nativemobile~20 mins

Expo modules in React Native - Mini App: Build & Ship

Choose your learning style9 modes available
Build: Camera Capture Screen
This screen lets users take a photo using the device camera and shows the captured image on the screen.
Target UI
┌─────────────────────────────┐
│        Camera Capture        │
├─────────────────────────────┤
│                             │
│        [Camera View]         │
│                             │
│                             │
│                             │
│                             │
│                             │
├─────────────────────────────┤
│   [Take Photo Button]        │
└─────────────────────────────┘
Use Expo Camera module to show live camera preview.
Add a button labeled 'Take Photo' below the camera preview.
When the button is pressed, capture a photo and display it below the button.
If a photo is captured, show the image on the screen.
Request camera permissions on screen load and handle permission denial gracefully.
Starter Code
React Native
import React, { useState, useEffect, useRef } from 'react';
import { View, Text, Button, Image, StyleSheet } from 'react-native';
import { Camera } from 'expo-camera';

export default function CameraCaptureScreen() {
  const [hasPermission, setHasPermission] = useState(null);
  const [photoUri, setPhotoUri] = useState(null);
  const cameraRef = useRef(null);

  useEffect(() => {
    (async () => {
      // TODO: Request camera permissions here
    })();
  }, []);

  const takePhoto = async () => {
    // TODO: Capture photo and save URI
  };

  return (
    <View style={styles.container}>
      {/* TODO: Show camera preview if permission granted */}
      {/* TODO: Show message if permission denied or null */}
      {/* TODO: Add Take Photo button */}
      {/* TODO: Show captured photo if available */}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 10
  },
  camera: {
    width: '100%',
    height: 300,
  },
  photo: {
    width: 300,
    height: 300,
    marginTop: 10
  }
});
Task 1
Task 2
Task 3
Task 4
Task 5
Task 6
Solution
React Native
import React, { useState, useEffect, useRef } from 'react';
import { View, Text, Button, Image, StyleSheet } from 'react-native';
import { Camera } from 'expo-camera';

export default function CameraCaptureScreen() {
  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 takePhoto = async () => {
    if (cameraRef.current) {
      const photo = await cameraRef.current.takePictureAsync();
      setPhotoUri(photo.uri);
    }
  };

  if (hasPermission === null) {
    return <Text>Requesting camera permission...</Text>;
  }

  if (hasPermission === false) {
    return <Text>No access to camera. Please allow camera permission.</Text>;
  }

  return (
    <View style={styles.container}>
      <Camera style={styles.camera} ref={cameraRef} />
      <Button title="Take Photo" onPress={takePhoto} />
      {photoUri && <Image source={{ uri: photoUri }} style={styles.photo} />}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 10
  },
  camera: {
    width: '100%',
    height: 300
  },
  photo: {
    width: 300,
    height: 300,
    marginTop: 10
  }
});

This solution uses the Expo Camera module to show a live camera preview. When the screen loads, it asks the user for camera permission. If permission is granted, the camera preview is shown. A button labeled 'Take Photo' lets the user capture a picture. The picture's URI is saved in state and displayed below the button as an image. If permission is denied or still loading, a friendly message is shown instead.

We use a ref to access the camera methods. The takePictureAsync() method captures the photo. The UI updates automatically to show the captured image. This app is simple and shows how to use Expo modules to access device features easily.

Final Result
Completed Screen
┌─────────────────────────────┐
│        Camera Capture        │
├─────────────────────────────┤
│  [Live Camera Preview Here] │
│                             │
│                             │
│                             │
│                             │
├─────────────────────────────┤
│   [Take Photo Button]        │
├─────────────────────────────┤
│  [Captured Photo Displayed]  │
│                             │
└─────────────────────────────┘
When the screen opens, it asks for camera permission.
If permission is granted, the live camera preview appears.
User taps 'Take Photo' button to capture an image.
The captured photo appears below the button.
If permission is denied, a message tells the user no access.
Stretch Goal
Add a button to switch between front and back cameras.
💡 Hint
Use Camera's 'type' prop and toggle between Camera.Constants.Type.front and Camera.Constants.Type.back.