Når vi utvikler applikasjoner i React, er det vanlig å begynne med en monolitisk komponent, en komponent som er ansvarlig for både datahåndtering og presentasjon av UI. Dette er en intuitiv tilnærming, men etter hvert som applikasjonen vokser, kan dette føre til problemer med vedlikehold, testing og gjenbruk. I denne delen av boken tar vi for oss hvordan du kan unngå monolitiske komponenter ved å dele opp funksjonaliteten i mindre, gjenbrukbare komponenter og gjøre bruk av render props for mer fleksibilitet og enklere administrasjon av komponentavhengigheter.
I utgangspunktet kan en monolitisk komponent se ut som en stor blokk som både håndterer tilstand (state) og rendering av UI-elementer. Dette kan føre til kode som er vanskelig å teste, feilbarlig og utfordrende å gjenbruke i andre deler av applikasjonen. For eksempel, i en komponent som håndterer både en liste av artikler og en form for å legge til nye artikler, kan det hende at både logikken for databehandling og presentasjonen er tett sammenkoblet. Dette gjør det vanskelig å endre eller utvide applikasjonen senere.
For å adressere dette problemet, er en løsning å bryte opp funksjonaliteten i mindre, gjenbrukbare komponenter. Et godt eksempel på dette er å separere en "Feature"-komponent som håndterer applikasjonens tilstand og forretningslogikk fra de komponentene som kun er ansvarlige for rendering. På denne måten kan applikasjonen håndtere tilstanden i en sentralisert komponent, mens små presentasjonskomponenter får de nødvendige dataene som props.
Render props, en teknikk som gjør det mulig å sende komponenter som funksjoner til andre komponenter, kan være en kraftig løsning for dette. Ved å bruke render props kan du sende funksjoner som returnerer komponenter i stedet for å importere dem direkte som avhengigheter. Dette gir stor fleksibilitet, ettersom du kan bytte ut en komponent med en annen uten å måtte endre på hovedkomponenten.
I praksis fungerer render props ved at en komponent mottar en funksjon som et prop. Denne funksjonen returnerer et JSX-element som skal renderes. For eksempel, i stedet for å importere en AddArticle eller ArticleList komponent direkte, kan du sende disse som funksjoner som props til hovedkomponenten, som deretter kan bruke dem til å fylle ut de nødvendige UI-elementene. Dette reduserer direkte avhengigheter og gjør komponentene lettere å gjenbruke i forskjellige deler av applikasjonen.
I koden, kan vi ha noe som dette:
Her ser vi at i stedet for å bruke AddArticle og ArticleList direkte, sendes de som render props som funksjoner til hovedkomponenten. Dette gjør det mulig å endre implementeringen av disse komponentene uten å måtte endre på hvordan hovedkomponenten håndterer dataene.
En annen viktig ting å merke seg er at React-komponenter ofte er delt opp i to kategorier: containere og presentasjonskomponenter. Container-komponenter håndterer vanligvis tilstanden i applikasjonen, mens presentasjonskomponenter kun er ansvarlige for hvordan dataene blir vist. Denne separasjonen gjør det lettere å gjenbruke komponentene, ettersom presentasjonskomponentene kan brukes i ulike deler av applikasjonen uten å være tett knyttet til en spesifikk tilstand eller datakilde.
Monoli
Hvordan bruke Lazy Components og Suspense for effektiv deling av kode i React-applikasjoner
I moderne webutvikling er ytelse et kritisk element, spesielt når det gjelder React-applikasjoner som kan vokse raskt i størrelse. For å håndtere den potensielle flaskehalsen som oppstår ved at store applikasjoner lastes i ett enkelt bundle, kan teknikker som "code splitting" og "lazy loading" brukes. Disse teknikkene gir muligheten til å laste bare den nødvendige koden ved behov, noe som forbedrer brukeropplevelsen betydelig ved å redusere initial lastetid.
React tilbyr flere mekanismer for å implementere denne strategien. En av de mest brukte metodene er bruken av React.lazy og Suspense. Disse komponentene hjelper til med å laste komponenter kun når de faktisk er nødvendige, og gir et enkelt fall-back for innholdet som ikke er lastet ennå.
Når vi bruker React.lazy(), kan vi definere komponenter som lastes asynkront. I koden som følger, kan vi se hvordan to komponenter, First og Second, kan lastes på en lat måte ved hjelp av React.lazy():
På denne måten vil ikke hele appen bli lastet med en gang. I stedet blir First og Second komponentene lastet når de faktisk trengs – for eksempel når brukeren navigerer til en spesifikk rute som krever at én av disse komponentene blir vist.
For å håndtere tilstandene mens komponentene lastes, benytter vi Suspense-komponenten som tilbyr en fallback-egenskap. Denne egenskapen bestemmer hva som skal vises til brukeren mens komponenten er i ferd med å laste:
Som nevnt, er Suspense plassert rundt de delene av applikasjonen hvor lat lading skjer, for eksempel når ruten for en side aktiveres. Når ruten for /first er valgt, vil First-komponenten bli lastet for første gang, og de nødvendige bundlefilene lastes samtidig. Fallbacken, som kan være en spinner eller et teksthint som "Laster...", vises mens innholdet er på vei inn i nettleseren.
Et viktig aspekt ved implementeringen av lazy loading er å unngå å gjøre komponentene lazy uten en god grunn. I tilfellene hvor flere komponenter er sterkt relaterte og alltid lastes samtidig, er det bedre å samle disse i ett bundle i stedet for å laste dem asynkront, ettersom dette kan føre til flere HTTP-forespørsler uten reell ytelsesgevinst.
Videre, i større applikasjoner som bruker en ruter som react-router, kan lazy loading være spesielt nyttig. Her er det viktig å forstå at ruter og deres respektive komponenter kan lastes på en lat måte, og at dette kan bidra til bedre organisering av applikasjonens kode og forbedret ytelse. Når en ny rute aktiveres, for eksempel /first, vil den respektive komponenten ikke bli lastet med en gang applikasjonen starter, men først når brukeren navigerer til den. Dette reduserer initial lastetid og holder applikasjonen responsiv.
Et annet poeng å merke seg er at for å få det beste ut av lazy loading, bør appen struktureres på en måte som reflekterer hvordan brukeren interagerer med den. Hvis en bruker for eksempel ofte navigerer mellom flere sider i applikasjonen, kan det være en fordel å dele appen opp i flere små, isolerte bundles som kun lastes når de er nødvendige.
For videre ytelsesforbedringer kan React-biblioteket også brukes sammen med verktøy som Webpack for å finjustere hvordan bundles blir generert og lastet. For eksempel kan Webpack bruke dynamisk import og lage separate bundles per komponent, noe som gir enda mer kontroll over hva og når koden blir lastet.
I sum gjør React.lazy og Suspense det enklere å håndtere store applikasjoner ved å tillate utviklere å laste komponenter asynkront, og dermed forbedre ytelsen betraktelig. Bruken av disse teknikkene er spesielt viktig i applikasjoner med mange sider eller komponenter som ikke nødvendigvis er nødvendige ved første lasting av applikasjonen.
Hva er forskjellen mellom Select og Radio Buttons i Material UI?
Når det kommer til brukergrensesnittdesign i Material UI, er det viktig å forstå hvordan forskjellige komponenter fungerer og når det er mest hensiktsmessig å bruke dem. En av de vanligste forskjellene mellom komponentene som brukes til valg i et skjema er hvordan Select og Radio Buttons håndterer visning og interaksjon.
Select-komponenter skiller seg fra Radio Buttons på flere måter, men den mest åpenbare forskjellen er hvordan de håndterer plasseringen på skjermen. Select-komponenter krever mindre plass fordi alternativene bare vises når brukeren åpner menyen. Dette gjør Select ideelt for situasjoner der du har flere valg, men ikke har plass til å vise dem alle på en gang. I eksempelet nedenfor ser vi hvordan Select-komponenten fungerer:
I dette eksempelet kontrollerer value-tilstanden hvilket alternativ som er valgt i Select-komponenten. Når brukeren endrer valget, oppdateres verdien ved hjelp av setValue()-funksjonen. MenuItem-komponenten definerer alternativene i Select-feltet, og value-egenskapen settes til tilstandens verdi når et gitt element er valgt.
En annen vanlig komponent for brukerinteraksjon er Radio Buttons, som er ideelle når det er behov for at brukeren velger ett alternativ fra en liten mengde alternativer, men der alle alternativene vises samtidig. I tilfelle Radio Buttons, vises alternativene alltid på skjermen, og valget er begrenset til ett alternativ om gangen.
En viktig forskjell mellom disse to komponentene er at Radio Buttons alltid er synlige, mens Select skjuler alternativene inntil brukeren aktivt åpner menyen. Dette betyr at Select-komponenter er mer plassbesparende, mens Radio Buttons kan gi en mer direkte interaksjon med brukeren.
En annen viktig komponent er TextField, som er nødvendig når brukeren trenger å skrive inn tekst. TextField krever ingen støttekomponenter og lar oss sette verdier og håndtere brukerens inndata enkelt. Et eksempel på bruk av TextField kan se slik ut:
I dette tilfellet er value-tilstanden knyttet til brukerens inndata, og verdien endres i henhold til hva brukeren skriver.
Når vi ser på knapper, som er en annen viktig komponent, ser vi at Material UI-knapper ligner på HTML-knappene, men de tilbyr mer funksjonalitet og integrasjon med temaer og layout i Material UI. Eksemplet nedenfor viser hvordan man kan lage knapper med forskjellige stiler:
Her bruker vi Stack-komponenten for å plassere knappene horisontalt, og hver knapp kan skifte farge når brukeren klikker på den. Material UI gjør det enkelt å eksperimentere med forskjellige varianter av knapper som "Contained", "Text", og "Outlined".
En annen måte å tilpasse utseendet på komponentene i Material UI er ved å bruke styled()-funksjonen, som lar oss lage komponenter med spesifikke stilinnstillinger basert på JavaScript-objekter. Eksemplet nedenfor viser hvordan man kan lage en tilpasset knapp med marginer og rundede hjørner:
Når du begynner å bruke tilpassede temaer, kan du endre utseendet på hele applikasjonen. Material UI gir oss muligheten til å bruke createTheme()-funksjonen for å lage et tema som gjelder for alle komponenter i applikasjonen. For eksempel kan du endre skrifttypen og marginene på MenuItem-komponentene som vist i dette eksempelet:
Med Material UI får vi et kraftig rammeverk som lar oss lage fleksible og tilpassede brukergrensesnittkomponenter. Fra valgkomponenter som Select og Radio Buttons til inputfelt og knapper, Material UI tilbyr alt du trenger for å bygge moderne applikasjoner med et konsistent og responsivt design.
Hvordan navigere mellom skjermer i React Native med Expo og React Navigation
I React Native-utvikling er navigasjon mellom skjermer en essensiell del av appens brukeropplevelse. Når du bygger apper, trenger du en måte å bevege deg fra én skjerm til en annen, og håndtere dynamiske data som må vises på forskjellige skjermbilder. I denne delen av boken går vi gjennom hvordan man setter opp navigasjon i en React Native-app ved hjelp av Expo og React Navigation.
For å komme i gang, må vi installere nødvendige avhengigheter. Bruk Expo for å installere de grunnleggende pakkene:
Disse pakkene er nødvendige for å bruke navigasjonen i appen. Videre, for å bruke stack navigatoren, trenger vi å installere ytterligere en pakke relatert til navigasjonspakken:
Når disse pakkene er installert, kan vi begynne å utvikle navigasjonen. Her er et eksempel på hvordan App-komponenten kan se ut:
Funksjonen createNativeStackNavigator() setter opp navigasjonen i appen. Den returnerer et objekt som har to hovedkomponenter: Screen og Navigator. Screen representerer skjermene som kan navigeres til, mens Navigator håndterer navigasjonen mellom disse skjermene. Den første argumenten til createNativeStackNavigator() er en liste over skjermene, og den andre argumenten definerer generelle navigasjonsvalg. I eksemplet over forteller vi navigatoren at “Home”-skjermen skal være standard skjerm.
Skjermkomponentene
En skjerm kan være hvilken som helst React Native-komponent. Det er ingen spesifikke krav til hvordan komponentene skal se ut, men de må håndtere navigasjonens egenskaper. For eksempel, her er hvordan Home-komponenten kan se ut:
Dette er et vanlig funksjonelt komponent i React. Når brukeren trykker på knappen, navigeres de til "Settings"-skjermen. Navigasjonsegenskapen navigation er tilgjengelig i komponentene via react-navigation og gjør det mulig å bruke ulike API-funksjoner som navigate(), som tar skjermens navn som parameter. I dette tilfellet navigerer vi til skjermen med navnet “Settings”.
For å gjøre navigasjonen type-sikker, bruker vi en type som kalles RootStackParamList. Denne typen inneholder informasjon om hvilke ruter appen støtter. Når vi definerer denne typen sammen med NativeStackScreenProps, kan vi være sikre på at vi får riktig navigasjons- og ruteparameterhåndtering. Eksemplet på RootStackParamList ser slik ut:
Tilbakeknappen og Navigasjonsbar
En interessant funksjon i React Navigation er at det automatisk legger til en navigasjonslinje øverst på skjermene dine. Denne linjen har en tilbake-knapp, som gjør det mulig for brukeren å gå tilbake til forrige skjerm. På Android-enheter vises også en tilbake-knapp utenfor appen, som gjør det enda enklere å navigere. Dette er et eksempel på hvordan den kan se ut på "Settings"-skjermen:
Når du trykker på knappen her, blir brukeren sendt tilbake til “Home”-skjermen. I tillegg vil tilbake-knappen i navigasjonslinjen gjøre det samme. Denne funksjonaliteten krever ingen ekstra koding fra utviklerens side, noe som sparer mye tid.
Ruteparametere
En annen viktig del av navigasjonen er håndtering av ruteparametere. På en nettside kan du for eksempel sende informasjon gjennom URL-en som en del av ruten. I React Navigation kan vi gjøre noe lignende ved å sende data når vi navigerer mellom skjermene. La oss ta en titt på et eksempel hvor vi sender en tittelparameter til en detaljer-skjerm.
Først definerer vi RootStackParamList med rutenavnene og eventuelle parametere:
I Home-komponenten kan vi sende forskjellige titler til Details-skjermen:
I Details-komponenten kan vi deretter hente ruteparametrene:
På denne måten kan vi dynamisk sende og vise data fra én skjerm til en annen.
Det er også viktig å merke seg at selv om vi kun sender en tittelparameter i dette eksemplet, kan du sende flere parametere etter behov. Å bruke ruteparametere på denne måten gjør appen mer dynamisk, og det gir bedre fleksibilitet i hvordan data håndteres mellom skjermene.
Hvordan implementere en dynamisk liste med sortering og filtrering i React Native
For å lage en funksjonell liste med sorterings- og filtreringsmuligheter i React Native, er det viktig å forstå hvordan man bruker FlatList-komponenten effektivt. På overflaten kan det virke som om FlatList ikke gjør så mye, men i virkeligheten er det en svært fleksibel og kraftig komponent som håndterer lister og gir innebygd støtte for scrolling. Dette er essensielt når du jobber med store datamengder.
FlatList er designet for å være generisk og effektiv, med muligheter for å håndtere oppdateringer i dataene og tilby en optimalisert scrolling-opplevelse. Den lar deg definere hvordan hvert enkelt element i listen skal se ut, og hvilke data som skal vises. Når du benytter deg av FlatList, gir du komponenten en liste med data som den vil bruke for å vise innholdet.
For å gjøre listen visuelt tiltalende og brukervennlig, er det nødvendig å definere stiler for både containeren og elementene i listen. Dette kan gjøres ved å bruke StyleSheet fra React Native:
I dette eksemplet har vi en container-stil som gir listen sin høyde, og en item-stil som sørger for at hvert element har et tydelig utseende med bakgrunnsfarge og tekstjustering. Uten slike stiler vil listen fremstå som en ustrukturert tekstsamling, som kan være vanskelig å lese.
Når du har grunnlaget for listen på plass, kan du begynne å legge til funksjoner som gir brukeren kontroll over innholdet. En vanlig funksjon er muligheten til å sortere og filtrere listen basert på ulike kriterier. Dette kan oppnås ved å introdusere ekstra komponenter som lar brukeren interagere med listen på en intuitiv måte.
Strukturen av komponentene
I en applikasjon med sorterings- og filtreringsfunksjoner, kan komponentene organiseres på en måte som skiller ansvarene mellom ulike deler av applikasjonen. Her er en typisk komponentstruktur for en liste med kontroller:
-
ListContainer: Den overordnede containeren som håndterer tilstanden til listen og gir funksjonalitet til de underliggende komponentene.
-
List: En stateless komponent som tar inn data fra
ListContainerog bruker FlatList til å vise elementene. -
ListControls: Denne komponenten holder kontrollene for filtrering og sortering som påvirker listen.
-
ListFilter: En kontroll for å filtrere elementene basert på en tekstverdi.
-
ListSort: En kontroll som lar brukeren endre sorteringen av listen.
-
FlatList: Selve komponenten som tar seg av rendering av elementene i listen.
Denne strukturen gjør det mulig å utvikle en applikasjon som er både modulær og lett å vedlikeholde. Hver komponent er ansvarlig for en spesifikk oppgave, og endringer i én komponent vil ikke nødvendigvis påvirke resten av applikasjonen.
Implementasjon av funksjoner
En av de viktigste aspektene ved å håndtere lister er å kunne filtrere og sortere dem på en effektiv måte. For å gjøre dette kan man bruke utility-funksjoner som filtrerer og sorterer listen basert på brukerens input. Her er et eksempel på hvordan dette kan implementeres:
I dette tilfellet definerer vi en funksjon som filtrerer listen basert på om teksten finnes i elementene, og deretter sorterer listen enten i stigende eller synkende rekkefølge.
Videre benytter vi React Native's useMemo-hook for å optimalisere beregningen av listen, slik at den kun blir oppdatert når filtrering eller sortering endres:
Denne tilnærmingen gjør at listen oppdateres dynamisk uten unødvendige beregninger.
Bruken av kontroller
Kontrollene for filtrering og sortering er ansvarlige for å endre tilstanden til listen. I ListControls komponenten kan vi legge til knapper eller tekstfelt som gjør det mulig for brukeren å filtrere eller endre sorteringsrekkefølgen. Dette gir en god brukeropplevelse og lar brukeren interagere med listen på en intuitiv måte.
Et eksempel på ListControls-komponenten kan være:
I dette eksemplet har vi et tekstfelt for søk og en knapp for å bytte sorteringsrekkefølge.
Viktige betraktninger
Når du implementerer slike funksjoner, er det viktig å forstå hvordan tilstandsbehandling fungerer i React Native. Ved å bruke hooks som useState og useMemo, kan du effektivt håndtere dynamiske endringer i listen og minimere unødvendige oppdateringer. I tillegg bør du være oppmerksom på ytelsen når du arbeider med store datamengder, spesielt når du bruker komponenter som FlatList som renderer innholdet dynamisk etter behov.
En annen viktig faktor er at designet av listen bør være responsivt, slik at det fungerer godt på både små og store skjermstørrelser. Det kan være nødvendig å justere utseendet og funksjonaliteten for å sikre at listen er brukervennlig på tvers av ulike enheter.

Deutsch
Francais
Nederlands
Svenska
Norsk
Dansk
Suomi
Espanol
Italiano
Portugues
Magyar
Polski
Cestina
Русский