03/02/2022
Billeder er en uundværlig del af næsten enhver moderne mobilapplikation. De beriger brugeroplevelsen, formidler information visuelt og gør apps mere engagerende. I React Native er håndteringen af billeder designet til at være både kraftfuld og fleksibel, uanset om billederne er statiske ressourcer, der er bundlet med appen, eller dynamiske billeder, der hentes fra netværket eller brugerens enhed.

React Native tilbyder en samlet måde at administrere billeder og andre mediefiler på tværs af både Android- og iOS-platformene. Dette forenkler udviklingsprocessen betydeligt, da du kan bruge den samme kodebase til at håndtere billeder på tværs af forskellige enheder og operativsystemer. Denne artikel vil dykke ned i de forskellige måder, hvorpå du kan arbejde med billeder i React Native, herunder hvordan frameworket håndterer billedafkodning for optimal ydeevne.
- Statisk Billedhåndtering: Den Lokale Ressource
- Dynamisk Billedhåndtering: Netværk og Data URI
- Billedafkodning og Ydeevne
- Billedcache og Netværksstrategier
- Brug af Nativt Bundtede Billeder
- Android Drawable Ressourcer (XML)
- iOS Camera Roll Optimering
- source-Egenskaben: Mere end bare en URI
- Bagrundsbilleder med ImageBackground
- Tilpasning af Billedcache på iOS
- Håndtering af Billeder fra Brugeren
- Spørgsmål og Svar (FAQ)
- Konklusion
Statisk Billedhåndtering: Den Lokale Ressource
Den mest ligefremme måde at tilføje et billede til din React Native-app på er at placere det et sted i din kildekode og referere til det ved hjælp af require-syntaksen. Dette minder om, hvordan du importerer JavaScript-moduler. Bundleren finder billedet i den samme mappe som den komponent, der kræver det.
<Image source={require('./min-ikon.png')} />En stor fordel ved denne tilgang er den automatiske håndtering af skærmtæthed. Du kan levere billeder i forskellige opløsninger ved at tilføje @2x og @3x suffikser til filnavnet. Hvis du har en struktur som:
. ├── knap.js └── img ├── tjek.png ├── [email protected] └── [email protected]Og din knap.js kode indeholder <Image source={require('./img/tjek.png')} />, vil bundleren automatisk vælge den korrekte version baseret på enhedens skærmtæthed. For eksempel vil [email protected] blive brugt på en iPhone 7, mens [email protected] vil blive brugt på en iPhone 7 Plus. Hvis der ikke findes en nøjagtig match, vælges den nærmeste passende mulighed.
Fordele ved Statiske Billeder via require:
- Ensartet system på Android og iOS.
- Billeder lever i samme mappe som din JavaScript-kode, hvilket gør komponenter selvstændige.
- Ingen global navneplads, hvilket eliminerer bekymringer om navnekollisioner.
- Kun de billeder, der faktisk bruges, pakkes ind i din app, hvilket holder appens størrelse nede.
- Tilføjelse og ændring af billeder kræver ikke genkompilering af appen; du kan opdatere simulatoren som normalt.
- Bundleren kender billeddimensionerne, så du behøver ikke at duplikere dem i koden.
- Billeder kan distribueres via npm-pakker.
Det er vigtigt at bemærke, at billednavnet i require skal være statisk kendt for, at dette kan fungere. Dynamiske stier som require('./' + icon + '.png') fungerer, så længe bundleren kan bestemme de potentielle stier ved kompileringstidspunktet.
Dynamisk Billedhåndtering: Netværk og Data URI
Mange billeder i din app vil ikke være tilgængelige ved kompileringstidspunktet, eller du vil måske indlæse dem dynamisk for at holde binærfilens størrelse nede. Til dette formål bruges en URI (Uniform Resource Identifier).
Netværksbilleder
For billeder, der hentes fra en fjernserver, skal du bruge uri-egenskaben i source-objektet. Det er stærkt anbefalet at bruge HTTPS for at opfylde App Transport Security-kravene på iOS.
<Image source={{ uri: 'https://reactjs.org/logo-og.png' }} style={{ width: 400, height: 400 }} />I modsætning til statiske ressourcer skal du manuelt angive dimensionerne (width, height) for netværksbilleder. React Native implementerer ikke den adfærd, som webbrowsere gør, hvor et billede indlæses som 0x0 og derefter justeres; dette ville føre til kumulative layoutskift (CLS), som forringer brugeroplevelsen. Ved at kræve dimensioner på forhånd sikrer React Native en mere stabil UI.
Du kan også konfigurere HTTP-verben, headers og en body for billedanmodningen via source-objektet:
<Image source={{ uri: 'https://reactjs.org/logo-og.png', method: 'POST', headers: { Pragma: 'no-cache', }, body: 'Din body her', }} style={{ width: 400, height: 400 }} />Data URI Billeder
Nogle gange modtager du kodede billeddata, f.eks. fra et REST API-kald, typisk i Base64-format. Du kan bruge 'data:' URI-skemaet til at vise disse billeder. Dette er især nyttigt for meget små og dynamiske billeder, som f.eks. ikoner fra en database.
<Image style={{ width: 51, height: 51, resizeMode: 'contain', }} source={{ uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg==', }} />Ligesom med netværksressourcer skal du manuelt angive billedets dimensioner, når du bruger en Data URI.
Billedafkodning og Ydeevne
Spørgsmålet om, hvordan man "afkoder" et React Native-billede, er centralt for ydeevne. I webbrowsere udføres billedafkodning ofte på hovedtråden, hvilket kan føre til frysninger i brugergrænsefladen (UI) eller "frame drops", især for store billeder. Dette er en afgørende forskel i React Native:
I React Native udføres billedafkodning på en separat tråd (eller baggrundstråd). Det betyder, at når et billede er downloadet (fra netværket) eller fundet (lokalt), vil selve processen med at omdanne rå billeddata til et visuelt display ikke blokere hovedtråden, der er ansvarlig for at gengive din UI. Dette er en indbygget optimering, der sikrer en glattere brugeroplevelse.
Som udvikler behøver du typisk ikke manuelt at "afkode" et billede i React Native. Frameworket tager sig automatisk af denne komplekse opgave i baggrunden. Du skal blot levere billedkilden (via require, uri eller data: URI), og React Native håndterer resten, herunder afkodningen. Selvom afkodningen kan tage et par millisekunder, er det sjældent mærkbart for brugeren, da appen allerede skal håndtere situationen, hvor billedet endnu ikke er downloadet (f.eks. ved at vise en placeholder).
Billedcache og Netværksstrategier
React Native giver dig kontrol over, hvordan netværkslaget interagerer med cachen via cache-egenskaben i source-objektet. Dette er afgørende for at optimere indlæsningstider og båndbreddeforbrug.
| Cache-strategi | Beskrivelse |
|---|---|
default | Bruger platformens standardstrategi. Typisk en balance mellem at bruge cache og genindlæse. |
reload | Data for URL'en indlæses fra den oprindelige kilde. Eksisterende cachedata bruges ikke til at opfylde anmodningen. Nyttigt for at sikre, at du altid får den seneste version. |
force-cache | Eksisterende cachedata bruges til at opfylde anmodningen, uanset alder eller udløbsdato. Hvis der ikke findes data i cachen, indlæses det fra den oprindelige kilde. God til offline-brug. |
only-if-cached | Eksisterende cachedata bruges til at opfylde en anmodning, uanset alder eller udløbsdato. Hvis der ikke findes data i cachen, gøres der intet forsøg på at indlæse data fra den oprindelige kilde, og anmodningen betragtes som mislykket. Perfekt til at vise data, kun hvis de er tilgængelige offline. |
<Image source={{ uri: 'https://reactjs.org/logo-og.png', cache: 'only-if-cached', }} style={{ width: 400, height: 400 }} />Brug af Nativt Bundtede Billeder
Hvis du bygger en hybrid-app (dels React Native UI, dels platformspecifik kode), kan du stadig bruge billeder, der allerede er bundtet ind i appen via Xcode asset catalogs (iOS) eller Android drawable/assets-mapper.
iOS Asset Catalogs og Android Drawable Folder
For billeder, der er inkluderet via Xcode asset catalogs eller i Android drawable-mappen, skal du bruge billednavnet uden filtypen:
<Image source={{ uri: 'app_ikon' }} style={{ width: 40, height: 40 }} />Disse tilgange giver ingen sikkerhedskontrol; det er op til dig at garantere, at billederne er tilgængelige i applikationen. Du skal også manuelt angive billeddimensionerne.

Android Assets Folder
For billeder i Android assets-mappen skal du bruge asset:/-skemaet:
<Image source={{ uri: 'asset:/app_ikon.png' }} style={{ width: 40, height: 40 }} />Android Drawable Ressourcer (XML)
Android understøtter indlæsning af drawable-ressourcer via XML-filtypen, hvilket giver dig mulighed for at bruge vektortegninger (Vector Drawables) til ikoner eller formtegninger (Shape Drawables). Du kan importere og bruge disse ressourcetyper på samme måde som andre statiske eller hybride ressourcer.
For statiske drawables, der ligger sammen med din JS-kode, bruges require eller import:
<Image source={require('./img/mit_ikon.xml')} style={{ width: 40, height: 40 }} />For drawables inkluderet i Android res/drawable-mappen, bruges ressourcenavnet uden filtypen:
<Image source={{ uri: 'mit_ikon' }} style={{ width: 40, height: 40 }} />En vigtig forskel for XML drawable-ressourcer er, at de skal refereres ved kompileringstidspunktet af Android-applikationen, da Android skal køre Android Asset Packaging Tool (AAPT) for at pakke ressourcen. Binær XML, som AAPT skaber, kan ikke indlæses over netværket af Metro. Hvis du ændrer mappen eller navnet på et XML-asset, skal du genopbygge Android-applikationen hver gang.
iOS Camera Roll Optimering
Når du viser billeder fra brugerens Kamera-rulle (f.eks. via et billedvalgsværktøj som expo-image-picker), gemmer iOS ofte flere størrelser af det samme billede. React Native er smart nok til at vælge den størrelse, der er tættest på den ønskede visningsstørrelse for at optimere ydeevnen. Du vil f.eks. ikke bruge et 3264x2448 billede som kilde, når du viser en 200x200 thumbnail. Hvis der er et præcist match, vælger React Native det; ellers bruges den første, der er mindst 50% større, for at undgå sløring ved skalering. Dette sker automatisk.
source-Egenskaben: Mere end bare en URI
I React Native er src-attributten for billeder omdøbt til source, og den tager ikke en streng, men et objekt med en uri-attribut. Dette designvalg er bevidst og giver en række fordele:
- Det tillader at vedhæfte metadata til objektet. For eksempel, når du bruger
require('./min-ikon.png'), tilføjer React Native automatisk information om billedets faktiske placering og dimensioner (bredde og højde) tilsource-objektet. Dette er grunden til, at du ikke behøver at angive dimensioner for statiske billeder. - Det er fremtidssikret. I fremtiden kan man f.eks. understøtte sprites, hvor et enkelt billedfil indeholder flere små billeder. I stedet for bare
{uri: ...}kunnesource-objektet indeholde{uri: ..., crop: {left: 10, top: 50, width: 20, height: 40}}, hvilket muliggør transparent spriting på alle eksisterende kaldesteder. - Det giver dig som udvikler mulighed for at annotere objektet med dine egne nyttige attributter, f.eks. information om billedets dimensioner, hvis du selv ønsker at beregne størrelsen, det skal vises i.
Bagrundsbilleder med ImageBackground
En almindelig funktion, som webudviklere efterspørger, er background-image. I React Native kan du opnå dette ved at bruge <ImageBackground>-komponenten. Denne komponent har de samme props som <Image> og giver dig mulighed for at placere andre komponenter som børn oven på billedet.
<ImageBackground source={{ ... }} style={{ width: '100%', height: '100%' }}> <Text>Indhold over billedet</Text></ImageBackground>Det er vigtigt at bemærke, at du skal angive nogle width og height stilattributter for <ImageBackground> for at den vises korrekt.
Tilpasning af Billedcache på iOS
På iOS er der en API til at overstyre React Natives standardgrænser for billedcachen. Dette er nyttigt for apps, der håndterer et stort antal billeder og har brug for mere kontrol over hukommelsesforbruget. Denne API skal kaldes fra din native AppDelegate-kode (f.eks. inden for didFinishLaunchingWithOptions).
RCTSetImageCacheLimits(4 * 1024 * 1024, 200 * 1024 * 1024);I dette eksempel sættes billedets størrelsesgrænse til 4 MB og den samlede cache-omkostningsgrænse til 200 MB. Dette giver en finjustering af, hvor meget hukommelse billedcachen må bruge.
Håndtering af Billeder fra Brugeren
Ofte vil du lade brugerne vælge billeder fra deres enheds galleri eller tage nye billeder med kameraet. Biblioteker som expo-image-picker (fra Expo-økosystemet) eller react-native-image-picker (for bare React Native CLI-projekter) gør dette til en leg. Disse biblioteker giver dig typisk en URI til det valgte billede, som du derefter kan bruge direkte i din <Image>-komponent:
// Efter billedet er valgt af brugeren med f.eks. expo-image-picker const [billedeUri, setBilledeUri] = useState(null); // ... if (!result.cancelled) { setBilledeUri(result.uri); // result.uri er den URI, du skal bruge } // ... {billedeUri && <Image source={{ uri: billedeUri }} style={{ width: 200, height: 200 }} />}Dette forbinder processen med at vælge et billede med processen for at vise det i din app.
Spørgsmål og Svar (FAQ)
Hvorfor skal jeg angive dimensioner for netværksbilleder?
React Native kræver, at du angiver width og height for billeder, der indlæses fra netværket, for at undgå "Cumulative Layout Shift" (CLS). Dette er en situation, hvor UI'en hopper rundt, når billeder indlæses, hvilket fører til en dårlig brugeroplevelse. Ved at kende dimensionerne på forhånd kan React Native reservere plads til billedet, før det er fuldt indlæst og afkodet.
Hvad betyder @2x og @3x suffikser?
Disse suffikser bruges til at levere billeder i forskellige opløsninger for at understøtte enheder med forskellige skærmtætheder (DPI - Dots Per Inch). @2x er typisk for Retina-skærme (dobbelt pixeltæthed), og @3x for endnu højere tætheder. React Native vælger automatisk den mest passende version baseret på enhedens skærm.
Afkoder React Native billeder på hovedtråden?
Nej, en af de store fordele ved React Native er, at billedafkodning udføres på en separat baggrundstråd. Dette forhindrer, at langsomme afkodningsprocesser blokerer hovedtråden, hvilket sikrer en flydende og responsiv brugergrænseflade, selv når store billeder indlæses.
Kan jeg bruge SVG-billeder?
React Native understøtter ikke indbygget SVG-billeder direkte via <Image>-komponenten, ligesom webbrowsere gør. Dog kan du bruge biblioteker som react-native-svg og react-native-svg-uri (eller lignende) til at gengive SVG-filer. For Android kan du også bruge Vector Drawables, som er XML-baserede vektorgrafikker, der understøttes direkte af Androids <Image>-komponent, hvis de er bundlet korrekt.
Hvad er forskellen på require('./billede.png') og { uri: 'http://eksempel.com/billede.png' }?
Forskellen ligger i, hvordan billederne håndteres og hvor de kommer fra:
require('./billede.png'): Bruges til statiske billeder, der er en del af din applikations pakke. Bundleren behandler dem ved kompileringstidspunktet, optimerer dem og inkluderer deres dimensioner automatisk. Dette er den foretrukne metode for lokale billeder.{ uri: 'http://eksempel.com/billede.png' }: Bruges til dynamiske billeder, der hentes fra en fjernserver eller er ressourcer, der ikke er bundlet med appen (f.eks. fra brugerens galleri). Du skal manuelt angive dimensionerne for disse billeder, og de indlæses ved kørselstidspunktet.
Konklusion
React Native tilbyder en robust og fleksibel løsning til billedhåndtering, der adresserer mange af de udfordringer, der er forbundet med at vise visuelle medier i mobile apps. Fra den enkle inklusion af statiske billeder med automatisk skærmtæthedsoptimering til den dynamiske indlæsning af netværksbilleder og den intelligente håndtering af billedafkodning på separate tråde, er frameworket designet til at levere en højtydende og flydende brugeroplevelse. Ved at forstå de forskellige metoder og de underliggende principper kan du udnytte React Natives fulde potentiale til at skabe visuelt rige og responsive applikationer.
Hvis du vil læse andre artikler, der ligner Billedhåndtering i React Native: Fra Statisk til Dynamisk, kan du besøge kategorien Mobiludvikling.
