expo-camera gives you a component in React that lets you see what your phone’s camera is seeing, whether it’s the front camera or the back one. You can change different settings of the camera like how much it zooms in, focus, the color balance, and whether the flash is on or off.
Using this Camera component, not only can you take pictures and record videos, but these are also saved in your app’s storage space. What’s more interesting is that this component can recognize faces and bar codes that show up in the camera view
Integrating camera functionality in mobile applications is a common requirement. For those using React Native with Expo, this task is made simpler. In this article, we’ll go through how to add a camera feature to a React Native app using Expo, explaining each part of the code in a straightforward way.
Before diving into the code, ensure you have a React Native project set up with Expo. Expo simplifies the process of using the camera, as it bundles the necessary APIs and permissions.
npx expo install expo-camera
import React, { useState, useEffect, useRef } from 'react';
import { Text, View, Pressable } from 'react-native';
import { Camera } from 'expo-camera';const CameraScreen = () => {
const [hasPermission, setHasPermission] = useState(null);
const [type, setType] = useState(Camera.Constants.Type.back);
const cameraRef = useRef(null);
useEffect(() => {
(async () => {
const { status } = await Camera.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
const takePicture = async () => {
if (cameraRef.current) {
let photo = await cameraRef.current.takePictureAsync();
console.log(photo);
}
};
const toggleCameraType = () => {
setType(
type === Camera.Constants.Type.back
? Camera.Constants.Type.front
: Camera.Constants.Type.back
);
};
if (hasPermission === null) {
return <View />;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<View style={{ flex: 1 }}>
<Camera style={{ flex: 1 }} type={type} ref={cameraRef}>
<View
style={{
flex: 1,
backgroundColor: 'transparent',
justifyContent: 'flex-end',
alignItems: 'center',
}}>
<Pressable onPress={takePicture}>
<Text style={{ fontSize: 18, marginBottom: 10, color: 'white' }}>Take Picture</Text>
</Pressable>
<Pressable onPress={toggleCameraType}>
<Text style={{ fontSize: 18, marginBottom: 10, color: 'white' }}>Flip Camera</Text>
</Pressable>
</View>
</Camera>
</View>
);
};
export default CameraScreen;
Now, let’s understand the code step-by-step.
Importing Necessary Modules
import React, { useState, useEffect, useRef } from 'react';
import { Text, View, Pressable } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { Camera } from 'expo-camera';
Here, we import:
- Essential React hooks (
useState
,useEffect
,useRef
) for managing state and references. - Components from React Native (
Text
,View
,Pressable
) for UI elements. useNavigation
from@react-navigation/native
for navigating between screens.Camera
fromexpo-camera
, which is the main component for camera functionality.
Creating The CameraScreen Component
const CameraScreen = () => {
const navigation = useNavigation();
const [hasPermission, setHasPermission] = useState(null);
const [type, setType] = useState(Camera.Constants.Type.back);
const cameraRef = useRef(null);
...
};
In this block:
- We declare the
CameraScreen
functional component. - Use
useNavigation
for navigation. - Define states for permission status (
hasPermission
) and camera type (type
). - Create a reference (
cameraRef
) to interact with the camera.
Handling Permissions and Effects
useEffect(() => {
(async () => {
const { status } = await Camera.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
This useEffect
hook:
- Is used to request camera permissions when the component mounts.
Camera.requestPermissionsAsync()
asks the user for camera access.- Sets
hasPermission
based on the user's response.
Taking a Picture
const takePicture = async () => {
if (cameraRef.current) {
let photo = await cameraRef.current.takePictureAsync();
console.log(photo);
}
};
This function:
- Checks if the camera is available (
cameraRef.current
). - Takes a picture using
takePictureAsync()
method. - Logs the photo object for now (can be used for further processing).
Toggling Camera Type
const toggleCameraType = () => {
setType(
type === Camera.Constants.Type.back
? Camera.Constants.Type.front
: Camera.Constants.Type.back
);
};
Rendering The Camera and UI
if (hasPermission === null) {
return <View />;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}return (
<View style={{ flex: 1 }}>
...
</View>
);
This part renders:
- A blank
View
if permission status is unknown. - A message if camera access is denied.
- The camera and buttons (to take a picture, flip the camera, and navigate to the profile) if access is granted.
Adding camera functionality in a React Native application using Expo is a streamlined process. The above code walks you through setting up the camera, handling permissions, and adding basic features like taking a picture and toggling the camera view. This integration enhances the app’s capabilities, making it more interactive and user-friendly