Videregivelse af data med props
Definér en genanvendelig komponent, der modtager props, videregiv værdier fra en overordnet komponent, og brug PropTypes eller TypeScript til at dokumentere de forventede prop-former.
Videregivelse af data med props er en gratis React Native Academy-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i React Native Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. React Native Academy-kurset indeholder 4 lektioner i alt.
Hvad er props?
Props (kort for properties) er den mekanisme, React-komponenter bruger til at modtage input fra deres overordnede komponent. En overordnet komponent viser en underordnet komponent og sender data til den gennem attributter i JSX — ligesom HTML-attributter, men for alle JavaScript-værdier, herunder strenge, tal, objekter, arrays og funktioner. Den underordnede komponent modtager alle sine props som ét objektargument. Props bevæger sig i én retning: fra overordnet komponent ned til underordnet komponent. En underordnet komponent kan aldrig ændre sine egne props — de er skrivebeskyttede.
import { Text, View } from 'react-native';
// Child component receives props
function Greeting({ name, age }) {
return (
<View>
<Text>Hello, {name}!</Text>
<Text>You are {age} years old.</Text>
</View>
);
}
// Parent passes data through props
export default function App() {
return (
<View style={{ flex: 1, padding: 24 }}>
<Greeting name='Alice' age={30} />
<Greeting name='Bob' age={25} />
</View>
);
}Destrukturering af props
Du kan tilgå props på to måder: som ét props-objekt (function Card(props) { props.title }) eller ved at destruere dem direkte i funktionssignaturen (function Card({ title, subtitle })). Destrukturering er den foretrukne stil, fordi den gør de accepterede props tydelige og koden mere kompakt. Du kan også angive standardværdier for props i destruktureringssyntaksen: { size = 16, color = '#333' }. Det betyder, at proppen er valgfri og falder tilbage til standardværdien, når den overordnede komponent ikke angiver den.
import { Text, View, StyleSheet } from 'react-native';
// Destructuring with default values
function Badge({ label, color = '#4f86f7', size = 14 }) {
return (
<View style={[styles.badge, { backgroundColor: color }]}>
<Text style={[styles.text, { fontSize: size }]}>{label}</Text>
</View>
);
}
export default function App() {
return (
<View style={{ gap: 8, padding: 16 }}>
<Badge label='New' /> {/* uses defaults */}
<Badge label='Sale' color='#e74c3c' /> {/* custom color */}
<Badge label='Pro' color='#2ecc71' size={12} />
</View>
);
}
const styles = StyleSheet.create({
badge: { paddingHorizontal: 10, paddingVertical: 4, borderRadius: 12, alignSelf: 'flex-start' },
text: { color: '#fff', fontWeight: 'bold' },
});Sådan sender du forskellige prop-typer
Props kan indeholde alle JavaScript-værdier. Strenge kræver ikke krøllede parenteser (title='Hello'), men alle andre typer gør — tal (count={5}), boolske værdier (disabled={true} eller blot disabled), objekter (style={{ color: 'red' }}), arrays (items={[1,2,3]}) og funktioner (onPress={handlePress}). At sende funktioner som props er den måde, underordnede komponenter kommunikerer tilbage til overordnede komponenter på — den overordnede komponent definerer funktionen og sender den ned, og den underordnede komponent kalder den, når noget sker. Dette mønster er centralt for Reacts ensrettede dataflow.
import { View, Text, TouchableOpacity } from 'react-native';
// onPress is a function prop — callback from child to parent
function ConfirmButton({ label, count, disabled, onPress }) {
return (
<TouchableOpacity
onPress={onPress}
disabled={disabled}
style={{ opacity: disabled ? 0.4 : 1, backgroundColor: '#4f86f7', padding: 12, borderRadius: 8 }}
>
<Text style={{ color: '#fff', fontWeight: 'bold' }}>
{label} ({count})
</Text>
</TouchableOpacity>
);
}
export default function App() {
return (
<View style={{ padding: 24 }}>
<ConfirmButton
label='Add to Cart'
count={3}
disabled={false}
onPress={() => console.log('Added!')}
/>
</View>
);
}Proppen children
Den særlige prop children indeholder det, du placerer mellem en komponents åbne- og lukketag. Det muliggør komposition — du kan bygge wrapper- eller containerkomponenter, der anvender layout, styling eller adfærd på alt indhold, der er indlejret i dem. React Natives View, ScrollView og TouchableOpacity fungerer alle på denne måde. Definér dine egne wrapperkomponenter med children for at oprette genanvendelige layoutskabeloner som kort, modaler og skærmskabeloner.
import { View, StyleSheet } from 'react-native';
// A Card wrapper that applies consistent styling
function Card({ children, style }) {
return (
<View style={[styles.card, style]}>
{children}
</View>
);
}
export default function App() {
return (
<View style={{ padding: 16 }}>
<Card>
{/* Any content can go inside the Card */}
<Text>Title</Text>
<Text>Subtitle</Text>
<Image source={{ uri: 'https://picsum.photos/200' }} style={{ width: 200, height: 100 }} />
</Card>
</View>
);
}
const styles = StyleSheet.create({
card: { backgroundColor: '#fff', borderRadius: 16, padding: 16, elevation: 3, marginBottom: 12 },
});Spredning af props med spread-operatoren
Brug JavaScripts spread-operator til at sende alle egenskaber i et objekt som individuelle props. Det er praktisk, når du har et dataobjekt med mange felter: <UserCard {...user} /> svarer til <UserCard id={user.id} name={user.name} avatar={user.avatar} />. Spread-mønsteret er almindeligt, når du viser elementer fra et array med .map(). Vær forsigtig med ikke at sprede ukendte props på indbyggede komponenter (View, Text) — det udløser advarsler eller ignoreres stiltiende. Spred kun props på brugerdefinerede komponenter, som du selv kontrollerer.
import { View, Text } from 'react-native';
const users = [
{ id: '1', name: 'Alice', role: 'Admin' },
{ id: '2', name: 'Bob', role: 'User' },
];
function UserRow({ name, role }) {
return (
<View style={{ padding: 12, borderBottomWidth: 1, borderBottomColor: '#eee' }}>
<Text style={{ fontWeight: 'bold' }}>{name}</Text>
<Text style={{ color: '#666' }}>{role}</Text>
</View>
);
}
export default function UserList() {
return (
<View>
{users.map(user => (
<UserRow key={user.id} {...user} />
))}
</View>
);
}TypeScript-props med interfaces
I TypeScript skal du definere formen på dine props ved hjælp af en interface eller type. Det opdager fejl ved kompilering — hvis du sender et tal, hvor der forventes en streng, eller glemmer en obligatorisk prop, vises der en fejl, før du overhovedet kører appen. Markér valgfrie props med ?. TypeScript giver også automatisk komplettering i editoren: Når du skriver <MyComponent i JSX, viser editoren alle tilgængelige props og deres typer. Det er en af de største produktivitetsfordele ved at bruge TypeScript i React Native-projekter.
import { View, Text, StyleSheet } from 'react-native';
interface ProductCardProps {
id: string;
name: string;
price: number;
imageUri: string;
badge?: string; // optional
onPress?: () => void; // optional callback
}
export default function ProductCard({
name,
price,
imageUri,
badge,
onPress,
}: ProductCardProps) {
return (
<View style={styles.card}>
<Text style={styles.name}>{name}</Text>
<Text style={styles.price}>${price.toFixed(2)}</Text>
{badge && <Text style={styles.badge}>{badge}</Text>}
</View>
);
}
const styles = StyleSheet.create({
card: { padding: 16, backgroundColor: '#fff', borderRadius: 12 },
name: { fontSize: 16, fontWeight: '600' },
price: { fontSize: 18, color: '#4f86f7', fontWeight: 'bold', marginTop: 4 },
badge: { color: '#e74c3c', fontSize: 12, marginTop: 4 },
});Callback-props: Kommunikation fra underordnet til overordnet komponent
Da data kun bevæger sig nedad i React, kommunikerer en underordnet komponent tilbage til sin overordnede komponent ved at kalde en callback-funktion, der er sendt som prop. Den overordnede komponent definerer funktionen (hvad der skal ske, når brugeren udfører en handling), sender den til den underordnede komponent, og den underordnede komponent kalder den på det rigtige tidspunkt. Dette er standardmønsteret for knapper, formularinput og listeelementer — den underordnede komponent behøver ikke vide, hvad der sker bagefter (ingen forretningslogik); den kalder blot proppen med relevante data.
import { View, Text, TouchableOpacity } from 'react-native';
// Child: knows nothing about business logic
function DeleteButton({ itemId, onDelete }) {
return (
<TouchableOpacity onPress={() => onDelete(itemId)}>
<Text style={{ color: 'red' }}>Delete</Text>
</TouchableOpacity>
);
}
// Parent: owns the logic and state
export default function ItemList() {
const [items, setItems] = React.useState(['Apple', 'Banana', 'Cherry']);
function handleDelete(index) {
setItems(prev => prev.filter((_, i) => i !== index));
}
return (
<View>
{items.map((item, i) => (
<View key={i} style={{ flexDirection: 'row', justifyContent: 'space-between', padding: 12 }}>
<Text>{item}</Text>
<DeleteButton itemId={i} onDelete={handleDelete} />
</View>
))}
</View>
);
}Undgå prop drilling
Prop drilling opstår, når du sender props gennem flere mellemliggende komponenter, der ikke selv har brug for dataene — de videresender dem blot længere ned. Det kan f.eks. være at sende et brugerobjekt fra App → Screen → Section → Card → Avatar kun for at vise avatarbilledet. Det bliver svært at vedligeholde, efterhånden som hierarkiet vokser. Løsningen er at bruge Context (til globale eller delte data som den loggede bruger eller temaet) eller at placere tilstanden sammen tættere på de komponenter, der har brug for den. Lad være med at overkonstruere tidligt — det er helt fint at sende props gennem nogle få niveauer.
// Prop drilling anti-pattern (not ideal when deep)
function App() {
const user = { name: 'Alice', avatar: 'https://...' };
return <Screen user={user} />;
}
function Screen({ user }) {
return <Section user={user} />; // just passing through
}
function Section({ user }) {
return <Avatar user={user} />; // just passing through
}
function Avatar({ user }) {
return <Image source={{ uri: user.avatar }} style={{ width: 40, height: 40 }} />; // actually uses it
}
// Solution: Context (covered later)
// Or: pass only the specific value needed at each level
function Section({ avatarUri }) { ... }
function Avatar({ uri }) { ... }Uforanderlige props: Hvorfor underordnede komponenter ikke kan ændre dem
En grundregel i React er, at en komponent aldrig må ændre sine egne props. Props er den overordnede komponents data, som sendes til den underordnede komponent til visning — de ejes af den overordnede komponent. Hvis en underordnet komponent har brug for at ændre en værdi, skal den kalde en callback-prop for at fortælle det til den overordnede komponent, som derefter opdaterer sin tilstand. Den overordnede komponent sender så den opdaterede værdi tilbage som en ny prop. Dette ensrettede flow gør dataændringer forudsigelige og nemme at fejlfinde — du ved altid, hvor tilstanden findes, og hvem der styrer den.
// WRONG: Never mutate props directly
function Counter({ count }) {
// This is an error — do not do this:
// count = count + 1;
return <Text>{count}</Text>;
}
// CORRECT: Notify parent via callback, parent updates state
function Counter({ count, onIncrement }) {
return (
<TouchableOpacity onPress={onIncrement}>
<Text>{count}</Text>
</TouchableOpacity>
);
}
// In the parent:
const [count, setCount] = useState(0);
<Counter count={count} onIncrement={() => setCount(c => c + 1)} />Realistisk eksempel på props: Feed-opslag
Anvend alle prop-begreberne på en realistisk komponent til et opslag i et feed på sociale medier. Komponenten modtager data fra feedlisten (tekst, billede, forfatter, antal likes, tidsstempel) samt callback-funktioner til brugerinteraktioner (like, kommentér, del). Komponenten er udelukkende præsentationsbaseret — alle data kommer ind gennem props, og alle interaktioner går ud gennem callback-props. Dette design gør FeedPost-komponenten nem at teste isoleret og genbruge på tværs af forskellige feed-typer (hjemmefeed, profilfeed, søgeresultater).
import { View, Text, Image, TouchableOpacity, StyleSheet } from 'react-native';
export default function FeedPost({
author, avatarUri, imageUri, caption, likes, timeAgo,
onLike, onComment, onShare
}) {
return (
<View style={styles.post}>
<View style={styles.header}>
<Image source={{ uri: avatarUri }} style={styles.avatar} />
<View>
<Text style={styles.author}>{author}</Text>
<Text style={styles.time}>{timeAgo}</Text>
</View>
</View>
<Image source={{ uri: imageUri }} style={styles.postImage} />
<Text style={styles.caption}>{caption}</Text>
<View style={styles.actions}>
<TouchableOpacity onPress={onLike}><Text>❤️ {likes}</Text></TouchableOpacity>
<TouchableOpacity onPress={onComment}><Text>💬 Comment</Text></TouchableOpacity>
<TouchableOpacity onPress={onShare}><Text>🔗 Share</Text></TouchableOpacity>
</View>
</View>
);
}
const styles = StyleSheet.create({
post: { backgroundColor: '#fff', marginBottom: 8 },
header: { flexDirection: 'row', alignItems: 'center', padding: 12, gap: 10 },
avatar: { width: 40, height: 40, borderRadius: 20 },
author: { fontWeight: 'bold', fontSize: 14 },
time: { fontSize: 12, color: '#999' },
postImage: { width: '100%', aspectRatio: 1 },
caption: { padding: 12, fontSize: 14 },
actions: { flexDirection: 'row', gap: 20, padding: 12, borderTopWidth: 1, borderTopColor: '#eee' },
});Standardprops med defaultProps
Ud over standardværdier i destruktureringen kan React-komponenter definere defaultProps som en statisk egenskab — et almindeligt objekt, der angiver fallback-værdier for hver valgfri prop. Når en prop er undefined (ikke sendt af den overordnede komponent), erstatter React den med værdien fra defaultProps. Dette mønster er ældre end standardværdier i destruktureringen og fungerer på samme måde, men er mindre almindeligt i moderne TypeScript-kodebaser, hvor standardværdier i interfaces foretrækkes. Begge tilgange giver samme resultat: Valgfrie props kan bruges sikkert uden null-tjek.
import { Text, View, StyleSheet } from 'react-native';
function Avatar({ size, color, initials }) {
return (
<View style={[styles.circle, { width: size, height: size, borderRadius: size / 2, backgroundColor: color }]}>
<Text style={styles.initials}>{initials}</Text>
</View>
);
}
// defaultProps: applied when prop is undefined
Avatar.defaultProps = {
size: 48,
color: '#4f86f7',
};
// Usage:
<Avatar initials='AB' /> // uses defaults: 48px blue
<Avatar initials='CD' size={64} /> // custom size, default color
<Avatar initials='EF' size={32} color='#e74c3c' /> // all custom
const styles = StyleSheet.create({
circle: { alignItems: 'center', justifyContent: 'center' },
initials: { color: '#fff', fontWeight: 'bold', fontSize: 16 },
});Hurtigt tjek
Test din forståelse af begreberne inden for React Native Mobile Development fra denne lektion.
Opsummering af lektionen
I denne lektion har du lært, at props er skrivebeskyttede værdier, der sendes fra overordnet til underordnet komponent i én retning, at callback-funktionsprops gør det muligt for underordnede komponenter at underrette overordnede komponenter om brugerhandlinger, og at TypeScript-interfaces dokumenterer og håndhæver den forventede prop-form ved kompilering. Dernæst ser vi på, hvordan du håndterer værdier, der ændrer sig, inde i komponenter med useState-hooket.
Lær JavaScript med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 30
- Lektioner
- 120
Ofte stillede spørgsmål
Er lektionen “Videregivelse af data med props” gratis?
Ja — alle 3 lektioner i læringssporet React Native Academy, inklusive “Videregivelse af data med props”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. React Native Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Videregivelse af data med props”?
Definér en genanvendelig komponent, der modtager props, videregiv værdier fra en overordnet komponent, og brug PropTypes eller TypeScript til at dokumentere de forventede prop-former. Du øver dig i React Native Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på React Native Academy?
Der kræves ingen tidligere erfaring. React Native Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.
Hvor lang tid tager lektionen “Videregivelse af data med props”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne React Native Academy-lektion?
Ja. Alle React Native Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Videregivelse af data med props
- Håndtering af komponenttilstand med useState
- Flytning af state op
- Opbygning af en interaktiv tællerapp