Cách tạo ứng dụng máy ảnh với Expo và React Native
Nếu bạn không quen với triển lãm, thì đó là một ứng dụng khách giúp bạn xây dựng các ứng dụng React Native với ít phức tạp hơn trong việc xây dựng. Nó cũng giúp bạn giải quyết những căng thẳng khi cài đặt và thiết lập môi trường để chạy React Native.
Trong hướng dẫn này, chúng tôi sẽ xây dựng một ứng dụng máy ảnh đơn giản, trong đó người dùng có thể chụp ảnh, xem trước ảnh của họ, sử dụng chế độ đèn flash và chuyển đổi giữa máy ảnh trước và sau.
Điều kiện tiên quyết
Expo không yêu cầu nhiều để bắt đầu xây dựng ứng dụng React Native đầu tiên của bạn. Bạn có thể tìm hiểu thêm về cách cài đặt expo và expo-cli tại đây trong tài liệu.
Lưu ý: trong hướng dẫn này, tôi sẽ sử dụng macOS và iOS. Bạn cũng có thể sử dụng Android, không có nhiều khác biệt khi sử dụng expo vào thời điểm này.
Bạn có thể cài đặt expo và expo-cli trên toàn cầu bằng cách chạy lệnh sau:
npm install --global expo-cli
Expo yêu cầu Nodejs để chạy. Bạn có thể chạy phiên bản mới nhất trên trang web chính thức tại đây.
Bắt đầu
Sau khi bạn đã cài đặt Expo và Nodejs, bạn có thể bắt đầu khởi động một dự án Expo mới bằng lệnh bên dưới:
expo init expo-camera-app
Cách cài đặt các gói và chạy ứng dụng
Expo cung cấp cho chúng tôi một ứng dụng khách để chúng tôi có thể chạy và xem bản xem trước của ứng dụng mà chúng tôi đang xây dựng. Nó có sẵn trên cả App Store và Google Play để tải xuống.
Đây là giao diện của ứng dụng.

Cách bắt đầu một dự án triển lãm
Truy cập thư mục ứng dụng và chạy ứng dụng.
cd expo-camera-app
Bạn sẽ được hỏi một số câu hỏi để chọn mẫu mặc định cho ứng dụng. Trong hướng dẫn này, chúng tôi chỉ cần chọn một tùy chọn trống (TypeScript), nhưng một lần nữa, bạn có thể tự do chọn những gì phù hợp với mình.

Chạy ứng dụng
Sau khi khởi động dự án, chúng tôi có thể chạy ứng dụng với expo run

Thao tác này sẽ mở ra một cửa sổ trong trình duyệt của bạn, nơi bạn có thể xem nhật ký. Nó cũng sẽ tạo mã QR mà bạn có thể quét để chạy ứng dụng trên thiết bị của mình.
Điều tốt về triển lãm là bạn không cần cài đặt và định cấu hình trình mô phỏng để chạy ứng dụng. Nó vẫn cung cấp cho bạn tùy chọn để chạy triển lãm trên trình mô phỏng, nhưng bạn phải tự cài đặt và định cấu hình trình mô phỏng.
Quay lại ứng dụng của chúng tôi. Giả sử bạn đã chạy thành công ứng dụng trên thiết bị, đây sẽ là màn hình mặc định:

Mở thư mục ứng dụng trong trình soạn thảo mã yêu thích của bạn. Tôi đang sử dụng VS Code.
Di App.tsx
chúc trông như thế này:
import {StatusBar} from 'expo-status-bar' import React from 'react' import {StyleSheet, Text, View} from 'react-native' export default function App() { return ( Open up App.tsx to start working on your app! ) } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center' } })
Cách tạo giao diện người dùng
Sau khi dự án chạy, bây giờ là lúc bắt đầu tạo một số giao diện người dùng.
Cài đặt camera hội chợ
Bước tiếp theo là cài đặt camera hội chợ, như sau:
expo install expo-camera
Chúng tôi sẽ tạo một giao diện người dùng đơn giản cho phép người dùng bắt đầu quá trình sử dụng máy ảnh.

import {StatusBar} from 'expo-status-bar' import React from 'react' import {StyleSheet, Text, View, TouchableOpacity} from 'react-native' export default function App() { return ( Take picture ) } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center' } })
Đó là một giao diện người dùng đơn giản: chúng tôi nhập TouchableOpacity
cho nút và thực hiện một số kiểu đơn giản. Nếu bạn đang thắc mắc về cách tạo kiểu hoạt động trong React Native, bạn có thể xem hai bài viết của tôi tại đây:
- Tạo kiểu trong React Native
- Làm sáng tỏ Flexbox trong React Native
Bây giờ chúng ta phải sử dụng useState
hook để quản lý trạng thái và hiển thị chế độ xem camera khi người dùng nhấn nút chụp ảnh .
Take picture
const [startCamera,setStartCamera] = React.useState(false) const __startCamera = ()=>{ }
Có hai điều quan trọng chúng ta phải làm khi người dùng nhấn nút:
- Yêu cầu quyền truy cập máy ảnh. Trong phát triển di động, việc truy cập nhiều API gốc và các tính năng di động thường bị hạn chế bởi quyền của người dùng và quyền riêng tư. Nó chỉ là thứ mà bạn phải làm quen khi phát triển ứng dụng di động.
- Change the state and present the camera.
Let's import the camera module from expo-camera
with this command:
import {Camera} from 'expo-camera'
And add the camera view, like this:
{ camera = r }} >
We can use ref
to access the camera's methods:
let camera: Camera
When the take picture
button is pressed the __startCamera
function will be called:
const __startCamera = async () => { const {status} = await Camera.requestPermissionsAsync() if(status === 'granted'){ // do something }else{ Alert.alert("Access denied") }
The function will ask for permission first. If the user grant access to the camera, we can proceed and open the camera. If not, we show a simple alert.
Add the camera component
Let's display the camera when the user grants access to the device's camera.
const __startCamera = async () => { const {status} = await Camera.requestPermissionsAsync() if (status === 'granted') { // start the camera setStartCamera(true) } else { Alert.alert('Access denied') } }
We have to make some changes to the UI and add a conditional rendering. We display the camera only when the user requests it, otherwise we display the default screen.
{startCamera ? ( { camera = r }} > ) : ( Take picture )}

Cool, now we need to add a button so we can take the actual picture.
Add the capture button

This is a simple View
inside the camera view that has an absolute position. So we make sure that it is always on the top of the camera.
How to take a picture
The app should take a picture when capture button is pressed. That function will look like the below:
const __takePicture = async () => { if (!camera) return const photo = await camera.takePictureAsync() }
First, we check that we have access to the Camera
component using ref
:
if (!camera) return // if the camera is undefined or null, we stop the function execution
Then we take the picture by calling the takePictureAsync
method. It returns a promise and an object that contains the picture's details. The result will look like this:
Object { "height": 4224, "uri": "file:///var/mobile/Containers/Data/Application/E6740A15-93AF-4120-BF11-6E8B74AFBF93/Library/Caches/ExponentExperienceData/%2540anonymous%252Fcamera-app-ee0fa3c8-1bb1-4d62-9863-33bf26341c55/Camera/19F0C5DD-7CA6-4043-8D89-AF65A1055C7E.jpg", "width": 1952, }
We are only interested in the Picture URL uri
. After we take a picture, we have to show the photo preview and hide the camera view. To do that we will use two hooks to change the state:
const [previewVisible, setPreviewVisible] = useState(false) const [capturedImage, setCapturedImage] = useState(null)
const __takePicture = async () => { if (!camera) return const photo = await camera.takePictureAsync() console.log(photo) setPreviewVisible(true) setCapturedImage(photo) }
setPreviewVisible
to show the previewsetCapturedImage(photo)
to store the object result
Then we display the preview like this:
{previewVisible && capturedImage ? ( ) : ( { camera = r }} > )}
The CameraPreview
component looks like this:
const CameraPreview = ({photo}: any) => { console.log('sdsfds', photo) return ( ) }
And the result looks like this:

How to re-take a picture
We can add some buttons to the preview that will allow the user to perform more actions. For example, they could re-take the photo or save it.

Add the savePhoto
and retakePicture
props to the CameraPreview
component like this:
When the Re-take
button is pressed, we will have to hide the preview, remove the current picture, and show the camera again. Do that with the following code:
const __retakePicture = () => { setCapturedImage(null) setPreviewVisible(false) __startCamera() }

How to add other options – back camera, flash, and more
expo-camra offers many options for customizing the camera, like FlashMode, setting the Camera type (front/back), zooming, and so on.
How to add FlashMode
Let's add an option so the user can turn FlashMode on and off:

We simply create a small button to switch off/on the flash, like this:
⚡️
And we just change the state when the button is pressed:
const [flashMode, setFlashMode] = React.useState('off') const __handleFlashMode = () => { if (flashMode === 'on') { setFlashMode('off') } else if (flashMode === 'off') { setFlashMode('on') } else { setFlashMode('auto') } }
And then we add FlashMode props:
{ camera = r }} >
How to access the front and the back camera
We will add a button that switches between the back and front camera.
We can get the default camera type directly from the camera module like below:
const [cameraType, setCameraType] = React.useState(Camera.Constants.Type.back)
Add type
props like this:
{ camera = r }} >
And add the switch button:
{cameraType === 'front' ? '?' : '?'}
And switch function:
const __switchCamera = () => { if (cameraType === 'back') { setCameraType('front') } else { setCameraType('back') } }
Here is the result:

You can find the full source code on GitHub.
Wrapping up
In general, Expo is an amazing tool that can save you a lot of time. It helps you start building directly and saves you the pain of environment setup.
Đôi khi bạn có thể muốn tạo một tiện ích mở rộng gốc và xử lý bằng cách sử dụng các tính năng gốc theo cách của riêng bạn. Trong trường hợp này, tôi khuyên bạn nên sử dụng CLI gốc phản ứng để bạn có thể sửa đổi và chơi với mã gốc một cách dễ dàng.
Xin chào, tên tôi là Hayani. Tôi đã tạo subscribei.io để giúp người sáng tạo, người viết blog và những người có ảnh hưởng phát triển lượng khán giả của họ thông qua bản tin.Tham gia danh sách Gửi thư của tôi nếu bạn muốn đọc thêm về React Native.