Skip to content

Hva med funksjoner + React?

Vi har i Funksjon sett på hvordan funksjoner fungerer i JavaScript og TypeScript. Men hva med React?

På slutten av Funksjon nevnte vi at en React-komponent er en funksjon som returnerer HTML-kode. La oss se litt nærmere på det.

Min første React-komponent

function MinKomponent() {
    return <div>Hei, jeg er en React-komponent!</div>
}
function MinKomponent(): React.ReactNode {
    return <div>Hei, jeg er en React-komponent!</div>
}   

Dette er en React-komponent. Den tar ingen argumenter, og returnerer en <div> med litt tekst.

MinKnapp

Vi lager en funksjon som tar inn et argument, og returnerer en knapp. Argumentet vi ønsker å ta inn skal si hva slags tekst som skal stå på knappen.

function MinKnapp(props) {
    return <button>{props.tekst}</button>
}

// brukes som

<MinKnapp tekst="Min Knapp" />
function MinKnapp(props: { tekst: string }): React.ReactNode {
    return <button>{props.tekst}</button>
}

// brukes som

<MinKnapp tekst="Min Knapp" />

En funksjon i React som definerer en React-komponent tar inn props som argument. props er et objekt som inneholder alle argumentene som du sender inn til komponenten. I dette tilfellet har vi definert at props skal ha et felt som heter tekst, som er en streng.

Funksjoner inne i funksjoner / React-komponenter

Vi kan bygge videre på MinKnapp. Be den gjøre noe når du trykker.

function MinKnapp(props) {
    function gjør_noe_ved_trykk() {
        console.log("Du trykket på knappen med teksten: " + props.tekst)
    }

    return <button onClick={gjør_noe_ved_trykk}>{props.tekst}</button>
}

<MinKnapp tekst="Trykk meg" />
function MinKnapp(props: { tekst: string }): React.ReactNode {
    function gjør_noe_ved_trykk() {
        console.log("Du trykket på knappen med teksten: " + props.tekst)
    }

    return <button onClick={gjør_noe_ved_trykk}>{props.tekst}</button>
}

<MinKnapp tekst="Trykk meg" />

Eksempler på argumenter i React-komponenter

Vi har sett i MinKnapp at vi kan ta inn argumenter i en React-komponent. La oss se på noen flere eksempler.

function MinKnapp(props) {
    return <button>{props.tekst}</button>
}

<MinKnapp tekst="Knappetekst" />
function MinKnapp(props: { tekst: string }) {
    return <button>{props.tekst}</button>
}

<MinKnapp tekst="Knappetekst" />

Her ser du at vi har definert at props skal ha et felt som heter tekst, som er en streng. Vi kan også lage en egen type for props, og bruke den i stedet for å definere det inline:

type MinKnappProps = {
    tekst: string;
}

function MinKnapp(props: MinKnappProps) {
    return <button>{props.tekst}</button>
}

<MinKnapp tekst="Knappetekst" />

Nå bruker vi tekst som et felt i props, og vi har definert en egen type for props som heter MinKnappProps. Dette gjør det enklere å lese og forstå koden, spesielt når vi utvidet komponentenen til å motta flere argumenter.

Noen ganger kan det være greit å destrukturere props i stedet for å bruke props.tekst. Da kan vi skrive det sånn:

const { tekst } = props; // hente ut tekst som en egen variabel fra props
const { tekst } = props; // hente ut tekst som en egen variabel fra props

I bruk i MinKnapp kan det se sånn her ut:

function MinKnapp(props) {
    const { tekst } = props; // hente ut tekst som en egen variabel fra props
    return <button>{tekst}</button>
}
function MinKnapp(props: { tekst: string }) {
    const { tekst } = props; // hente ut tekst som en egen variabel fra props
    return <button>{tekst}</button>
}

Legge til flere felt? Ingen problem!

function MinKnapp(props: { navn: string; tekst: string; }) {
    function gjør_noe_ved_trykk() {
        console.log("Jeg ble trykket på av " + props.navn)
    }
    return <button onClick={gjør_noe_ved_trykk}>{props.tekst}</button>
}

// eller

function MinKnapp(props: { navn: string; tekst: string; }) {
    const { navn, tekst } = props;

    function gjør_noe_ved_trykk() {
        console.log("Jeg ble trykket på av " + navn)
    }
    return <button onClick={gjør_noe_ved_trykk}>{tekst}</button>
}

// eller destrukturere direkte i argumentlista

function MinKnapp({ navn, tekst }: { navn: string; tekst: string; }) {
    function gjør_noe_ved_trykk() {
        console.log("Jeg ble trykket på av " + navn)
    }
    return <button onClick={gjør_noe_ved_trykk}>{tekst}</button>
}

Alle de tre funksjonene/komponentene gjør akkurat det samme.

Når argumentlisten blir lengre kan det være greit å lage en egen type for props på utsiden, og bruke den i stedet for å definere det inline. Da kan vi skrive det sånn her:

type MinKnappProps = {
    navn: string;
    tekst: string;
}

function MinKnapp({ navn, tekst }: MinKnappProps) {
    function gjør_noe_ved_trykk() {
        console.log("Jeg ble trykket på av " + navn)
    }
    return <button onClick={gjør_noe_ved_trykk}>{tekst}</button>
}

Her ser du at vi først definerer en type MinKnappProps som har to felt, navn og tekst, begge av typen string. Deretter bruker vi denne typen i argumentlisten til MinKnapp, og destrukturerer props direkte i argumentlisten.

props: MinKnappProps - her ser du samme skrivemåte som når du definerer en variabel. alder: number, eller navn: string. Så har du sagt at props er av typen MinKnappProp. Ingen magi, kun en helt vanlig måte å definere en variabel på.


Hvorfor har du gjør_noe_ved_trykk inne i MinKnapp da? Hvorfor er den ikke utenfor?

Fordi gjør_noe_ved_trykk kun gir mening i kontekst av knappen min, og ingenting annet i hele programmet mitt er interessert i den funksjonen. Når den ligger inni MinKnapp er den kun tilgjengelig for MinKnapp og ingen adnre. Det gjør at jeg i en annen knapp kan ha en funksjon med samme navn, uten at det blir kræsj.