Skicka data med props
Definiera en återanvändbar komponent som tar emot props, skicka värden från en överordnad komponent och använd PropTypes eller TypeScript för att dokumentera förväntade prop-former.
Skicka data med props är en gratis lektion i React Native Academy på CoddyKit. Detta är lektion 1 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för React Native Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i React Native Academy innehåller totalt 4 lektioner.
Vad är props?
Props (förkortning av properties) är mekanismen som React-komponenter använder för att ta emot indata från sin förälder. En förälder renderar en barnkomponent och skickar data till den genom attribut i JSX — precis som HTML-attribut, men för alla JavaScript-värden, inklusive strängar, tal, objekt, arrayer och funktioner. Barnkomponenten tar emot alla sina props som ett enda objektargument. Props flödar i en riktning: från förälder till barn. En barnkomponent kan aldrig ändra sina egna props — de är skrivskyddade.
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 av props
Du kan komma åt props på två sätt: som ett enda props-objekt (function Card(props) { props.title }) eller genom att destrukturera dem direkt i funktionssignaturen (function Card({ title, subtitle })). Destrukturering är den rekommenderade stilen eftersom den tydliggör vilka props som accepteras och gör koden mer koncis. Du kan också ange standardvärden för props i destruktureringssyntaxen: { size = 16, color = '#333' }. Det innebär att propen är valfri och får standardvärdet när den inte tillhandahålls av föräldern.
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' },
});Skicka olika propstyper
Props kan innehålla alla typer av JavaScript-värden. Strängar behöver inte klamrar (title='Hello'), men alla andra typer gör det — tal (count={5}), booleska värden (disabled={true} eller bara disabled), objekt (style={{ color: 'red' }}), arrayer (items={[1,2,3]}) och funktioner (onPress={handlePress}). Att skicka funktioner som props är hur barn kommunicerar tillbaka till föräldrar — föräldern definierar funktionen och skickar den nedåt, och barnet anropar den när något händer. Det här mönstret är centralt för Reacts enkelriktade dataflöde.
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>
);
}Propen children
Den särskilda propen children innehåller det du placerar mellan en komponents öppnings- och stängningstaggar. Det möjliggör komposition — du kan bygga omslutande komponenter eller containerkomponenter som tillämpar layout, styling eller beteende på valfritt innehåll som nästlas inuti. React Natives View, ScrollView och TouchableOpacity fungerar alla på det här sättet. Definiera egna omslutande komponenter med children för att skapa återanvändbara layoutskal, till exempel kort, modaler och skärmmallar.
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 },
});Spridning av props med spread-operatorn
Använd JavaScripts spread-operator för att skicka alla egenskaper i ett objekt som individuella props. Det är praktiskt när du har ett dataobjekt med många fält: <UserCard {...user} /> motsvarar <UserCard id={user.id} name={user.name} avatar={user.avatar} />. Spread-mönstret är vanligt när du renderar objekt från en array med .map(). Var försiktig så att du inte sprider okända props på inbyggda komponenter (View, Text) — det utlöser varningar eller ignoreras tyst. Sprid endast props på anpassade komponenter som du själv kontrollerar.
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 interface
I TypeScript definierar du formen på dina props med ett interface eller type. Det fångar fel vid kompilering — om du skickar ett tal där en sträng förväntas eller glömmer en obligatorisk prop visas ett fel innan du ens kör appen. Markera valfria props med ?. TypeScript aktiverar också automatisk komplettering i editorn: när du skriver <MyComponent i JSX listar editorn alla tillgängliga props och deras typer. Det här är en av de största produktivitetsfördelarna med att använda TypeScript i React Native-projekt.
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 från barn till förälder
Eftersom data i React bara flödar nedåt kommunicerar ett barn tillbaka till sin förälder genom att anropa en callback-funktion som skickats som prop. Föräldern definierar funktionen (vad som ska hända när användaren agerar), skickar den till barnet och barnet anropar den vid rätt tidpunkt. Det här är standardmönstret för knappar, formulärfält och listobjekt — barnkomponenten behöver inte bry sig om vad som händer sedan (ingen affärslogik), utan anropar bara prop-funktionen med relevanta 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>
);
}Undvik prop drilling
Prop drilling uppstår när du skickar props genom flera mellanliggande komponenter som inte själva behöver datan — de vidarebefordrar den bara djupare. Det kan till exempel innebära att du skickar ett user-objekt från App → Screen → Section → Card → Avatar bara för att visa avatarbilden. Det blir svårt att underhålla när hierarkin växer. Lösningen är att använda Context (för globala eller delade data, till exempel den inloggade användaren eller temat) eller att samplacera state närmare komponenterna som behöver det. Överkonstruera inte tidigt — några nivåer av prop-vidarebefordran är helt okej.
// 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 }) { ... }Oföränderliga props: varför barn inte kan ändra dem
En grundregel i React är att en komponent aldrig får ändra sina egna props. Props är förälderns data som skickas till barnet för visning — de ägs av föräldern. Om ett barn behöver ändra ett värde ska det anropa en callback-prop för att meddela föräldern, som sedan uppdaterar sitt state. Föräldern skickar därefter tillbaka det uppdaterade värdet som en ny prop. Det här enkelriktade flödet gör dataändringar förutsägbara och möjliga att felsöka — du vet alltid var state finns och vem som styr det.
// 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)} />Props i praktiken: inlägg i ett flöde
Tillämpa alla prop-koncept på en realistisk komponent för ett inlägg i ett flöde på sociala medier. Komponenten tar emot data från flödeslistan (text, bild, författare, antal gilla-markeringar och tidsstämpel) samt callback-funktioner för användarinteraktioner (gilla, kommentera och dela). Komponenten är helt presentationsinriktad — all data kommer in via props och alla interaktioner går ut via callback-props. Den här designen gör komponenten FeedPost enkel att testa isolerat och återanvända i olika typer av flöden (hemflöde, profilflöde och sökresultat).
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
Utöver standardvärden i destruktureringen kan React-komponenter definiera defaultProps som en statisk egenskap — ett vanligt objekt som anger reservvärden för varje valfri prop. När en prop är undefined (inte skickad av föräldern) ersätter React den med värdet från defaultProps. Det här mönstret är äldre än standardvärden i destruktureringen och fungerar på samma sätt, men är mindre vanligt i moderna TypeScript-kodbaser där standardvärden i interface föredras. Båda metoderna ger samma resultat: valfria props kan användas säkert utan null-kontroller.
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 },
});Snabbtest
Testa dina kunskaper om React Native Mobile Development-koncepten från den här lektionen.
Sammanfattning av lektionen
I den här lektionen lärde du dig att props är skrivskyddade värden som skickas från förälder till barn i en riktning, att callback-funktionsprops gör det möjligt för barn att meddela föräldrar om användaråtgärder och att TypeScript-interface dokumenterar och säkerställer den förväntade prop-formen vid kompilering. Härnäst utforskar vi hur du hanterar värden som ändras inuti komponenter med useState-hooken.
Lär dig JavaScript med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 30
- Lektioner
- 120
Vanliga frågor
Är lektionen ”Skicka data med props” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen React Native Academy, inklusive ”Skicka data med props”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i React Native Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Skicka data med props”?
Definiera en återanvändbar komponent som tar emot props, skicka värden från en överordnad komponent och använd PropTypes eller TypeScript för att dokumentera förväntade prop-former. Ni övar på React Native Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig React Native Academy?
Du behöver inga förkunskaper. Utbildningen i React Native Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.
Hur lång tid tar lektionen ”Skicka data med props”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här React Native Academy-lektionen?
Ja. Varje React Native Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Skicka data med props
- Hantera komponenttillstånd med useState
- Lyfta upp tillstånd
- Bygga en interaktiv räknarapp