Sådan oprettes en kameraapp med Expo og React Native
Hvis du ikke er fortrolig med expo, er det en klient, der hjælper dig med at opbygge React Native-apps med mindre build-kompleksitet. Det hjælper dig også med at håndtere stresset ved installation og opsætning af dit miljø til at køre React Native.
I denne vejledning bygger vi en simpel kameraapp, hvor brugeren kan tage billeder, se eksempler på deres billeder, bruge flashtilstand og skifte mellem det forreste og det bageste kamera.
Forudsætninger
Expo kræver ikke meget for at starte opbygningen af din første React Native-app. Du kan lære mere om installation af expo og expo-cli her i dokumenterne.
Bemærk: i denne vejledning bruger jeg macOS og iOS. Du kan også bruge Android, der er ikke meget forskel, når du bruger expo på dette tidspunkt.
Du kan installere expo og expo-cli globalt ved at køre følgende kommando:
npm install --global expo-cli
Expo kræver Nodejs for at køre. Du kan køre den nyeste version på det officielle websted her.
Kom godt i gang
Når du har installeret Expo og Nodejs, kan du starte bootstrapping af et nyt Expo-projekt med kommandoen nedenfor:
expo init expo-camera-app
Sådan installeres pakkerne og kører appen
Expo giver os en klientapp, hvor vi kan køre og se eksemplet på den app, vi bygger. Den er tilgængelig i både App Store og Google Play til download.
Dette er app-grænsefladen.

Sådan initieres et expo-projekt
Gå til appmappen, og kør appen.
cd expo-camera-app
Du bliver bedt om et par spørgsmål for at vælge standardskabelonen til appen. I denne vejledning vælger vi blot en tom (TypeScript) -indstilling, men igen er du fri til at vælge, hvad der passer til dig.

Kør appen
Efter bootstrapping af projektet kan vi køre appen med expo run

Dette åbner et vindue i din browser, hvor du kan se logfilerne. Det genererer også en QR-kode, som du kan scanne for at køre appen på din enhed.
Det gode ved expo er, at du ikke behøver at installere og konfigurere simulatorerne til at køre appen. Det giver dig stadig mulighed for at køre expo på simulatoren, men du skal selv installere og konfigurere simulatoren.
Tilbage til vores app. Forudsat at du med succes har kørt appen på enheden, vil dette være standardskærmen:

Åbn app-biblioteket i din foretrukne kodeditor. Jeg bruger VS-kode.
Den App.tsx
vil se sådan ud:
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' } })
Sådan oprettes brugergrænsefladen
Efter at have kørt projektet, er det nu tid til at begynde at oprette noget brugergrænseflade.
Installer expo-kamera
Det næste trin er at installere expo-kamera, som dette:
expo install expo-camera
Vi opretter en simpel brugergrænseflade, der giver brugeren mulighed for at starte processen med at bruge kameraet.

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' } })
Det er et simpelt brugergrænseflade: vi importerer TouchableOpacity
til knappen og laver en simpel styling. Hvis du spekulerer på, hvordan styling fungerer i React Native, kan du tjekke mine to artikler her:
- Styling i React Native
- Afmystificering af Flexbox i React Native
Nu skal vi bruge en useState
krog til at styre tilstanden og vise kameravisningen, når brugeren trykker på knappen tage billedet .
Take picture
const [startCamera,setStartCamera] = React.useState(false) const __startCamera = ()=>{ }
Der er to vigtige ting, vi skal gøre, når brugeren trykker på knappen:
- Bed tilladelse om at få adgang til kameraet. I mobiludvikling er adgang til mange native API'er og mobilfunktioner ofte begrænset af brugerens tilladelser og privatlivets fred. Det er bare noget, du skal vænne dig til, når du udvikler mobilapps.
- Skift tilstand, og præsenter kameraet.
Lad os importere kameramodulet fra expo-camera
med denne kommando:
import {Camera} from 'expo-camera'
Og tilføj kameravisningen som denne:
{ camera = r }} >
Vi kan bruge ref
til at få adgang til kameraets metoder:
let camera: Camera
Når take picture
der trykkes på knappen, kaldes __startCamera
funktionen:
const __startCamera = async () => { const {status} = await Camera.requestPermissionsAsync() if(status === 'granted'){ // do something }else{ Alert.alert("Access denied") }
Funktionen beder først om tilladelse. Hvis brugeren giver adgang til kameraet, kan vi fortsætte og åbne kameraet. Hvis ikke, viser vi en simpel advarsel.
Tilføj kamerakomponenten
Lad os vise kameraet, når brugeren giver adgang til enhedens kamera.
const __startCamera = async () => { const {status} = await Camera.requestPermissionsAsync() if (status === 'granted') { // start the camera setStartCamera(true) } else { Alert.alert('Access denied') } }
Vi er nødt til at foretage nogle ændringer i brugergrænsefladen og tilføje en betinget gengivelse. Vi viser kun kameraet, når brugeren anmoder om det, ellers viser vi standardskærmen.
{startCamera ? ( { camera = r }} > ) : ( Take picture )}

Sejt, nu skal vi tilføje en knap, så vi kan tage det faktiske billede.
Tilføj optageknappen

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.
Nogle gange vil du måske opbygge en indbygget udvidelse og håndtere brug af indfødte funktioner på din egen måde. I dette tilfælde vil jeg anbefale at bruge den reaktive native CLI, så du nemt kan ændre og spille med native kode.
Hej, mit navn er Said Hayani. Jeg oprettede subscribi.io for at hjælpe skabere, bloggere og influencere med at få deres publikum til at vokse gennem nyhedsbrevet.Deltag i min mailingliste, hvis du er interesseret i at læse mere om React Native.