Serverkommunikation og datahåndtering på webapplikationer har gennemgået en markant udvikling siden internettets tidlige dage. I begyndelsen, med HTTP 1.0, var internettets kommunikation statisk og simpel, hvor web-sider blev hentet i deres helhed sammen med statiske filer som billeder og stylesheets. Disse anmodninger medførte en ny opkobling hver gang, og interaktiviteten var minimal, ofte kun begrænset til HTML-formularer. Den første æra af serverkommunikation var præget af langsommere forbindelser og lavere sikkerhed, hvilket afspejlede webens spæde start.

Med fremkomsten af AJAX (Asynchronous JavaScript and XML) i slutningen af 1990'erne blev websider langt mere dynamiske. AJAX gjorde det muligt for applikationer at kommunikere med servere i baggrunden uden at skulle reloade hele siden. Den teknologiske grundsten var objektet XMLHttpRequest, som kunne sende data til servere og modtage svar uden at forstyrre brugerens interaktion med siden. Dette repræsenterede et væsentligt skift i, hvordan serverkommunikation blev håndteret.

Et simpelt eksempel på en XMLHttpRequest kunne se således ud:

javascript
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() { if (xhr.readyState == XMLHttpRequest.DONE) { if (xhr.status === 200) { console.log(xhr.responseText); } else { console.error('Error fetching data'); } } };
xhr.open('GET', 'http://example.com', true);
xhr.
send();

Her håndteres succes- og fejlrespons gennem callback-funktioner, som var den dominerende måde at håndtere asynkrone operationer på i AJAX'ens tid. Selvom dette var et skridt fremad, var det stadig et kode-mæssigt tungt arbejde, og man kunne hurtigt ende med uoverskuelige funktioner.

Med tiden blev HTTP opgraderet til version 1.1, som gjorde det muligt at holde forbindelser åbne mellem anmodninger og standardisere RESTful API'er. REST API'er anvender de grundlæggende HTTP-metoder som GET, POST, PUT og DELETE og definerer ressourcer med klare URI'er, hvilket har gjort applikationer mere skalerbare og lettere at arbejde med.

Senere kom Fetch API’et, som moderniserede datatrækningen med en promise-baseret tilgang, der giver en mere fleksibel og mindre kompleks måde at håndtere netværksanmodninger på i forhold til XMLHttpRequest. Et eksempel på en Fetch-anmodning kunne være:

javascript
fetch('http://example.com/data') .then(response => response.json())
.then(data => console.log(data))
.
catch(error => console.error('Error:', error));

Udviklingen stoppede dog ikke her. Ud over de grundlæggende teknologier som XMLHttpRequest og Fetch er der flere værktøjer, der er bygget på toppen af disse teknologier for at forenkle og forbedre arbejdet med serverkommunikation. Et af de mest populære er Axios, som er en HTTP-klientbibliotek, der forbedrer Fetch med funktioner som forespørgselsinterceptorer. Dette gør det muligt at for eksempel automatisere håndtering af autentificeringstokens. Her er et eksempel på Axios:

javascript
axios.get('http://example.com/data')
.then(response => console.log(response.data))
.catch(error => console.error('Error:', error));

Axios' styrke ligger i dens evne til at intercept requests og responses, hvilket sparer tid og reducerer kode, især når man arbejder med f.eks. token-refresh i real-time applikationer. Denne funktionalitet gør det lettere at håndtere sessioner og reducere redundans i koden, hvilket kan være en stor fordel i større projekter.

Et endnu mere fleksibelt alternativ er GraphQL, som grundlæggende ændrede måden, vi arbejder med API’er på. I stedet for at anmode om faste endepunkter, kan klienten præcist definere, hvilken data der skal hentes, hvilket mindsker risikoen for over- og under-fetching. Dette gør GraphQL ekstremt effektivt, da man kun får præcis de data, man har brug for. Et simpelt eksempel på GraphQL-anmodning:

javascript
import { GraphQLClient, gql } from 'graphql-request'; const endpoint = 'http://example.com/graphql'; const client = new GraphQLClient(endpoint); const query = gql` query {
user(id: 123) {
name email
} } `; client.request(query) .then(data => console.log(data))
.catch(error => console.error('Error:', error));

Her anmoder vi kun om de nødvendige felter, name og email, hvilket sparer båndbredde og forbedrer applikationens ydeevne.

I React-verdenen har biblioteker som React Query gjort det muligt at abstrahere meget af kompleksiteten ved datatrækning og state management. React Query håndterer bagvedliggende logik som caching, baggrundsopdatering og fejlbehandling uden at det er nødvendigt at skrive meget kode. Dette gør det lettere for udviklere at fokusere på at bygge funktionalitet fremfor at håndtere asynkrone tilstande manuelt. Et eksempel på brugen af React Query:

javascript
import { useQuery } from 'react-query'; function UserProfile({ userId }) { const { data, error, isLoading } = useQuery(userId, fetchUser);
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>; return ( <div> {data.name} Email: {data.email} </div> ); }

Med React Query bliver håndtering af asynkrone data en næsten automatisk proces, hvor udvikleren ikke selv behøver at tænke på håndtering af loading states eller fejl.

En anden spændende teknologi i denne udvikling er WebSockets, som muliggør realtids, tovejskommunikation mellem server og klient. Denne teknologi har været en game-changer for applikationer, der kræver live opdateringer som chat-applikationer eller finansielle trading-platforme. Eksempel på en WebSocket-forbindelse:

javascript
const socket = new WebSocket('ws://example.com'); socket.onopen = function(event) { console.log('Connection established'); }; socket.onmessage = function(event) {
console.log('Message from server ', event.data);
}; socket.
onerror = function(error) { console.error('WebSocket Error ', error); };

WebSockets muliggør en konstant, åben forbindelse, hvilket gør det muligt at sende og modtage data i realtid, hvilket åbner op for nye muligheder i applikationer, hvor tid er en kritisk faktor.

I sidste ende er udviklingen af serverkommunikation et afgørende aspekt af webudvikling. Fra de første primitive HTTP-anmodninger til moderne API-teknologier som GraphQL og React Query har vi set en udvikling, der ikke kun har forbedret ydeevnen men også gør udviklernes liv lettere. Det er teknologier, der ikke kun letter arbejdet med datatrækning, men også sørger for en mere robust og brugercentreret oplevelse.

Hvordan man udvikler applikationer til flere platforme: Web, mobil og desktop med React og React Native

React har etableret sig som et af de mest populære JavaScript-biblioteker til udvikling af moderne webapplikationer. I denne bog vil vi dykke ned i både React og React Native og udforske, hvordan man effektivt udvikler applikationer, der kan køre på web, mobil og desktop. Bogen er rettet mod JavaScript-udviklere, der har et grundlæggende kendskab til JavaScript, HTML og CSS, men som ikke nødvendigvis har erfaring med React. Målet er at lære, hvordan man kan udnytte Reacts kraftfulde funktioner til at bygge fleksible og højtydende applikationer.

Indledningsvis giver vi en forståelse af, hvad React er, og hvorfor det er et godt valg for applikationsudvikling. React adskiller sig fra traditionelle JavaScript-frameworks ved at tilbyde en komponentbaseret tilgang, hvor hver del af brugergrænsefladen (UI) behandles som en isoleret enhed. Denne tilgang gør det muligt at skabe dynamiske, interaktive og vedligeholdelsesvenlige webapplikationer, der er lette at skalere.

En vigtig del af React er JSX, et markup-sprog, der gør det muligt at skrive HTML-lignende kode i JavaScript. Dette giver en mere naturlig syntaks og gør koden lettere at forstå. Når man arbejder med React, er det vigtigt at forstå, hvordan man bygger og håndterer komponenter, som er de grundlæggende byggesten i enhver React-applikation. Hooks, en nyere funktion i React, spiller en central rolle i at håndtere tilstand og sideeffekter på en funktionel og enkel måde.

For at kunne håndtere interaktioner med brugeren, lærer vi at arbejde med events på den "React-måde". React tilbyder en effektiv måde at håndtere brugerinput og eventuelle ændringer i UI’et. Derudover dækker bogen, hvordan man skaber genanvendelige komponenter, hvilket ikke kun forbedrer applikationens struktur, men også reducerer den kode, der skal vedligeholdes.

Bogen går også i dybden med typekontrol og validering via TypeScript, som er et superset af JavaScript, der tilføjer statisk typekontrol til sproget. TypeScript gør det lettere at arbejde med store applikationer, da det kan hjælpe med at identificere potentielle fejl, før de opstår i runtime.

Når applikationen vokser, bliver det nødvendigt at implementere routing for at navigere mellem forskellige visninger. React-router, et populært bibliotek til håndtering af routing, forklares grundigt i bogen, så du kan bygge applikationer, der kan navigere mellem sider uden at opdatere hele siden.

Desuden dækker bogen, hvordan man implementerer "code splitting" ved hjælp af lazy loading og Suspense, som gør det muligt at indlæse komponenter kun når de er nødvendige. Dette øger applikationens ydeevne og sikrer en bedre brugeroplevelse, især når applikationen bliver større og mere kompleks.

Når du begynder at arbejde med applikationer på flere platforme, lærer du, hvordan du kan bruge Material-UI (MUI), et populært komponentbibliotek for React, til at skabe moderne og responsive brugergrænseflader. Material-UI gør det muligt at bygge professionelle UI’er hurtigt og nemt.

Et andet vigtigt emne i bogen er håndtering af tilstand i React-applikationer. Her præsenteres forskellige tilstandshåndteringsbiblioteker, som Redux og Mobx. Disse værktøjer hjælper med at centralisere applikationens tilstand, hvilket gør det lettere at administrere og debugge applikationer, især når de bliver mere komplekse.

Når vi ser på udvikling af mobilapplikationer, forklares forskellene mellem React og React Native. React Native gør det muligt at bygge native mobilapplikationer ved hjælp af de samme teknologier, som vi bruger til webapplikationer. I modsætning til webapplikationer, der kører i en browser, kører React Native-applikationer direkte på mobilens operativsystem, hvilket giver en højere ydeevne og en mere integreret brugeroplevelse.

For at komme i gang med React Native, viser bogen, hvordan man opsætter et udviklingsmiljø, og hvordan man kan opbygge en grundlæggende React Native-applikation. Derudover forklares det, hvordan man arbejder med flexbox til at skabe responsive layout, samt hvordan man navigerer mellem forskellige skærme i applikationen.

I React Native er det også muligt at integrere funktioner som geolocation og kort, håndtere brugerinput via formularer, reagere på brugerens bevægelser og meget mere. Bogen giver konkrete eksempler på, hvordan man implementerer disse funktioner på en effektiv måde, så du kan skabe funktionelle og interaktive mobilapplikationer.

Når det kommer til performance, lærer du hvordan du håndterer opdateringer af applikationens tilstand på en måde, der sikrer høj ydeevne. React har indbygget funktioner som "shouldComponentUpdate" og "React.memo", der gør det muligt at undgå unødvendige rendering’er, hvilket gør applikationen hurtigere og mere responsiv.

Server-side rendering (SSR) er et andet avanceret emne, der forklares i bogen. Med Next.js kan du bygge React-applikationer, der renderes på serveren, hvilket forbedrer SEO og reducerer den tid, det tager at vise den første visning af applikationen til brugeren.

Unit tests er også en vigtig del af moderne applikationsudvikling, og bogen dækker, hvordan man kan bruge testing frameworks som Vittest til at sikre, at applikationen fungerer som forventet. At skrive tests gør det lettere at vedligeholde applikationen, og det hjælper med at fange fejl tidligt i udviklingsprocessen.

React Native giver også mulighed for at arbejde med offline-funktionalitet, så applikationer kan fungere uden en aktiv internetforbindelse. Dette er især vigtigt for mobilapplikationer, hvor netværksforbindelser kan være ustabile eller fraværende.

Det er vigtigt at forstå, at React og React Native ikke er statiske teknologier. De udvikler sig hurtigt, og nye funktioner og opdateringer kommer løbende. Derfor er det vigtigt at holde sig opdateret med de nyeste ændringer og best practices, som kan hjælpe med at forbedre både udviklingsoplevelsen og den endelige brugeroplevelse.

Hvordan React Native udvider funktionalitet og håndterer opdateringer

React Native har revolutioneret udviklingen af mobilapplikationer ved at tilbyde et effektivt værktøj til at bygge apps, der kører på både iOS og Android med en enkelt kodebase. Én af de mest markante fordele ved React Native er dens evne til at opdatere applikationer hurtigt og uden forsinkelse, hvilket adskiller den fra traditionelle metoder, hvor apps skal verificeres og godkendes af Apple eller Google. Dette åbner op for en langt mere fleksibel og agil udviklingsproces, som er muligt gennem tjenester som Microsoft’s CodePush og Expo’s OTA (Over-the-Air) opdateringer.

Når det kommer til JS-biblioteker (som ikke kræver native moduler), er der næsten ingen begrænsninger i brugen. Det betyder, at udviklere kan benytte sig af et væld af allerede eksisterende og velkendte biblioteker som Moment, Lodash, Axios, Redux, MobX og mange andre. Dette giver stor frihed til hurtigt at udvide en applikation med funktionalitet uden at skulle bygge hver enkelt komponent fra bunden. Der findes endda et projekt, React Native Directory, som samler og vurderer tusindvis af biblioteker og gør det nemt at finde den nødvendige pakke til et specifikt behov.

Når vi ser nærmere på hvordan React Native fungerer internt, bliver det tydeligt, at der er mange komponenter og API’er tilgængelige, som gør det muligt at bygge stærke og interaktive applikationer. React Native’s arkitektur tilbyder en række grundlæggende byggesten, som næsten alle apps vil bruge på et eller andet niveau. Disse komponenter omfatter blandt andet:

  • View: Den fundamentale byggesten, som alle andre komponenter kan indlejres i. På mobile enheder svarer dette til UIView på iOS eller android.view på Android.

  • Text: En komponent til visning af tekst, som understøtter indlejring, styling og berøringshåndtering.

  • Image: Bruges til at vise billeder fra diverse kilder som netværksbilleder, statiske ressourcer eller billeder fra kamerarullen.

  • TextInput: Gør det muligt for brugere at indtaste tekst via tastaturet og understøtter funktioner som autokorrektion og auto-kapitalisering.

  • ScrollView: En container til at håndtere scrollbare indholdsområder, som understøtter både vertikal og horisontal scrolling.

  • Button og Pressable: Brugt til oprettelse af knapper og andre berørbare komponenter, hvor Pressable giver mere præcis kontrol over brugerens berøring.

  • Switch: En komponent, der ligner en checkbox, men præsenteret som en switch, som vi kender fra mobile enheder.

Disse komponenter udgør grundlaget for en app’s brugergrænseflade og interaktivitet. I de kommende kapitler vil vi dykke dybere ned i de forskellige komponenter og deres specifikationer. Eksempler på, hvordan man kombinerer disse komponenter for at skabe apps, vil blive grundigt udforsket, hvilket giver udviklere de nødvendige værktøjer til at bygge effektive og responsive mobilapplikationer.

En af de vigtigste aspekter ved udvikling i React Native er forståelsen af, hvordan man udvider funktionaliteten af applikationen. React Native’s åbne økosystem betyder, at det er muligt at integrere et væld af tredjepartsbiblioteker og -moduler, hvilket gør det muligt at tilpasse og udvide appens funktionalitet hurtigt og effektivt. For udviklere, der ønsker at udvide deres applikationer, er React Native Directory et uundværligt værktøj, da det indeholder en omfattende samling af nyttige biblioteker og moduler, som kan integreres i en eksisterende app.

Der er dog vigtige overvejelser, når man arbejder med React Native. For det første kan brugen af native kode og tredjepartsmoduler indføre visse tekniske udfordringer. Det er nødvendigt at have et grundlæggende kendskab til mobiludvikling for at kunne navigere effektivt mellem de native iOS og Android-komponenter. Derudover er det vigtigt at tage højde for potentielle problemer med kompatibilitet mellem forskellige versioner af React Native og de biblioteker, man vælger at bruge. Det kan være nødvendigt at bruge særlige værktøjer som Expo for at lette udviklingsprocessen, især hvis du ikke har erfaring med native udvikling.

Det er også værd at bemærke, at selvom Expo har gjort det lettere at arbejde med React Native, især for nybegyndere, er der stadig nogle begrænsninger. Tidligere kunne Expo ikke håndtere tilpasning af native kode, men denne begrænsning er blevet løftet, hvilket betyder, at udviklere nu har større frihed til at integrere egen native kode i deres projekter. Dette gør Expo til et endnu mere attraktivt valg for udviklere, der ønsker at undgå de komplekse processer, der følger med brugen af React Native CLI, samtidig med at de stadig har adgang til de kraftfulde funktioner, som React Native tilbyder.

Endvidere er det vigtigt at forstå, at React Native, selvom det giver mange fordele i form af hurtigere udvikling og deling af kodebase, ikke er en one-size-fits-all løsning. Der er situationer, hvor det er mere hensigtsmæssigt at bruge native udvikling på én platform, især hvis applikationen kræver meget specifik hardwareinteraktion eller platformafhængige funktioner. Desuden bør udviklere være opmærksomme på, at mens React Native gør det lettere at bygge cross-platform apps, betyder det ikke nødvendigvis, at der ikke vil være udfordringer i form af performance og platform-specifikke bugs.

Hvordan Navigering Mellem Skærme Fungerer i React Navigation

I denne sektion vil vi udforske, hvordan navigation mellem forskellige skærme fungerer i React Navigation, og hvordan man bruger route-parametre til at undgå at skrive duplikerede komponenter. Når du arbejder med navigering i en React Native-applikation, er det vigtigt at forstå, hvordan man håndterer og manipulerer navigationens header samt hvordan man konfigurerer skærme med forskellige navigationsmuligheder.

Når du navigerer mellem skærme, kan du bruge route.params til at sende specifik data mellem skærme. Dette gør det muligt for applikationen at opdatere visse elementer dynamisk baseret på de parametre, der sendes til en skærm. For eksempel, når du navigerer fra en "Home"-skærm til en "Details"-skærm, kan du sende data som f.eks. titel, indhold og lagerstatus (stock). Dette giver dig mulighed for at opdatere både indholdet og navigationsheaderen uden at skulle skabe nye komponenter for hver situation.

På en "Home"-skærm kan der være knapper, som hver især sender forskellige parametre til "Details"-skærmen. Når brugeren klikker på en af disse knapper, vil de blive sendt videre til "Details"-skærmen, og den relevante information vil blive vist. Dette sparer både tid og ressourcer, da du ikke behøver at duplikere din komponentkode. Ved at benytte navigation.navigate() og sende parametre med, kan du genbruge den samme skærmkomponent og få den til at reagere dynamisk på de data, der er relevante for den aktuelle navigation.

En vigtig del af denne proces er håndteringen af navigationsheaderen. I eksemplet med en "Details"-skærm, som vi tidligere har set, kan du opdatere navigationens header dynamisk ved hjælp af navigation.setOptions(). På denne måde kan du tilføje en titel til skærmen og ændre knapperne i navigationen baseret på de parametre, der sendes til den. Dette gør det muligt at skabe en mere fleksibel og dynamisk brugeroplevelse, da navigationens indhold kan tilpasses til den aktuelle skærm og kontekst.

Det er også vigtigt at forstå, at headerRight-muligheden kan bruges til at tilføje knapper til navigationsbaren. Dette kan være nyttigt, hvis du for eksempel vil tilføje en "Køb"-knap, som skal være aktiv eller deaktiveret afhængigt af lagerstatus. Hvis lageret er tomt, kan knappen blive deaktiveret ved at tjekke værdien af en parameter som route.params.stock. Dette giver en mere interaktiv og kontekstbaseret navigering, hvor handlinger kan blive aktiveret eller deaktiveret på baggrund af de data, du arbejder med.

Når vi taler om at navigere mellem skærme, er det også nyttigt at forstå, hvordan man kan bruge tab- og drawer-navigering, som giver brugeren en alternativ måde at navigere på i appen. Tab-navigation, der ofte bruges til at skabe en bunke af skærme med ikoner nederst på skærmen, og drawer-navigation, der åbner en menu fra siden af skærmen, er to yderligere metoder til at håndtere navigation. Disse navigationsmuligheder kan implementeres forskelligt afhængigt af platformen, hvilket betyder, at du kan vælge at bruge tab-navigation på iOS og drawer-navigation på Android, eller du kan vælge at bruge samme navigationsmetode på begge platforme. Denne fleksibilitet kan være vigtig, da det gør det muligt at tilpasse appens navigation efter de specifikke behov for de enkelte platforme.

Det er også relevant at installere de nødvendige biblioteker, som @react-navigation/bottom-tabs og @react-navigation/drawer, og sikre, at du har de rette native moduler som react-native-gesture-handler og react-native-reanimated, når du arbejder med drawer-navigation. Derudover skal du sikre dig, at du opdaterer din babel.config.js for at støtte animationer, som kan være nødvendige for at få navigationen til at fungere glat.

For at opsummere:

  1. Parametre i navigation gør det muligt at sende data mellem skærme uden at duplikere kode.

  2. Dynamiske navigation headers kan tilpasses med funktioner som navigation.setOptions() for at ændre indhold baseret på de data, der er sendt til skærmen.

  3. Fleksibilitet i navigationsmetoder giver dig mulighed for at bruge tab- og drawer-navigation afhængigt af platformen og brugernes præferencer.

  4. Interaktive elementer som knapper kan aktiveres eller deaktiveres dynamisk, baseret på data, hvilket forbedrer brugeroplevelsen.

Endtext

Hvordan man laver API-anmodninger fra React Native-komponenter

Når du arbejder med API-anmodninger i React Native, vil du opdage, at det at hente data fra en ekstern kilde fungerer på en meget lignende måde som i webapplikationer. React Native understøtter fetch()-metoden, som allerede er polyfyldt, hvilket betyder, at den er tilgængelig uden behov for yderligere installation. Dette gør netværkskoden i dine mobile applikationer nem at skrive og forstå, fordi den følger de samme principper, som du allerede kender fra udvikling af webapplikationer.

I et typisk React Native-projekt kan du oprette en mock API ved at bruge funktioner, der returnerer promises, ligesom fetch()-metoden gør. For eksempel kan du oprette et array af objekter, som kan bruges som data for en liste:

javascript
const items = new Array(100).fill(null).map((v, i) => `Item ${i}`);
function filterAndSort(data: string[], text: string, asc: boolean) { return data .filter((i) => text.length === 0 || i.includes(text)) .sort( asc
? (a, b) => (b > a ? -1 : a === b ? 0 : 1)
:
(a, b) => (a > b ? -1 : a === b ? 0 : 1) ); }

I eksemplet ovenfor kan du bruge en funktion som fetchItems() til at hente data fra en API, der er simuleret med de filtrerede og sorterede elementer. Dette opretter en simpel API, der kan returnere data som en promise, hvilket gør den let at håndtere i et React Native-komponent.

Når du implementerer en komponent som ListContainer, kan du begynde at hente data via API'en og vise det i din brugergrænseflade. Dette kan gøres ved at bruge React Hooks som useState og useEffect:

javascript
export default function ListContainer() { const [asc, setAsc] = useState(true); const [filter, setFilter] = useState(""); const [data, setData] = useState([]); useEffect(() => { fetchItems(filter, asc) .then((resp) => resp.json()) .then(({ items }) => { setData(mapItems(items)); }); }, []); }

Dette kodeudsnit henter data fra API'en, når komponenten først bliver monteret. Du kan derefter bruge de relevante funktioner til at opdatere listen, når brugeren ændrer filteret eller rækkefølgen på dataene.

Lazy loading af liste-data

Når du arbejder med meget store datamængder, er det ofte en god idé at implementere en funktion som "lazy loading". Dette betyder, at du kun henter de data, som er nødvendige i øjeblikket, i stedet for at hente hele datasættet på én gang. Dette er særligt nyttigt i applikationer, hvor brugeren ikke nødvendigvis ved, hvad de søger efter, og hvor en uendelig rullefunktion kan bruges. Tænk på Facebooks nyhedsfeed, hvor indholdet hentes dynamisk, når du ruller ned på siden.

I React Native kan du bruge en komponent som FlatList til at implementere uendelig rulling. Når brugeren når bunden af listen, kan du hente flere data:

javascript
function* genItems() {
let cnt = 0; while (true) { yield `Item ${cnt++}`; } }

Med generatorer som genItems() kan du oprette en datakilde, der genererer nye elementer, hver gang du har brug for mere data. Når du implementerer denne funktionalitet i din komponent, vil listen blive opdateret, når brugeren når bunden af listen. Dette gør det muligt at have en uendelig rullende liste, der kun henter data, når det er nødvendigt, og undgår at overbelaste hukommelsen.

javascript
export function fetchItems({ refresh }: { refresh?: boolean }) {
if (refresh) { items = genItems(); } return Promise.resolve({ json: () => Promise.resolve({ items: new Array(30).fill(null).map(() => items.next().value as string), }), }); }

Når dataene er blevet hentet, kan du opdatere din liste med de nye elementer, og bruge den opdaterede data som kilde til din FlatList.

Implementering af "Pull to Refresh"

En almindelig interaktion på mobile enheder er "pull to refresh"-gesten, som gør det muligt for brugeren at opdatere indholdet af en liste eller en side ved at trække den ned. Dette blev først introduceret af Loren Brichter i 2009 i hans app Tweetie og har siden været standard i mange mobile applikationer. Apple har integreret denne funktionalitet i deres SDK som UIRefreshControl.

I React Native kan du bruge FlatList's onRefresh-propertie til at implementere denne funktion:

javascript
type Props = { data: { key: string; value: string }[]; fetchItems: () => Promise; refreshItems: () => Promise; isRefreshing: boolean; };
export default function List({
data, fetchItems, refreshItems, isRefreshing, }: Props
) {
return ( <FlatList data={data} renderItem={({ item }) => <Text>{item.value}</Text>} onEndReached={fetchItems} onRefresh={refreshItems} refreshing={isRefreshing} /> ); }

Her håndterer onRefresh funktionen, som bliver kaldt, når brugeren trækker ned for at opdatere listen. Denne funktion kan bruges til at hente de nyeste data og opdatere listen. Når listen er under opdatering, vil refreshing-propertien vise en indlæsningsindikator.

I din ListContainer-komponent kan du implementere funktionaliteten til at opdatere listen ved hjælp af setIsRefreshing-metoden:

javascript
const [isRefreshing, setIsRefreshing] = useState(false); function fetchItems() { return api .fetchItems({}) .then((resp) => resp.json()) .then(({ items }) => { setData([ ...data, ...items.map((value) => ({ key: value, value, })), ]); }); } function refreshItems() { setIsRefreshing(true);
fetchItems().finally(() => setIsRefreshing(false));
}

Ved at implementere denne funktionalitet kan du gøre din applikation mere interaktiv og brugervenlig, da den giver brugeren mulighed for hurtigt at opdatere listen med nye data.

Endtext