Chapitre 1 · Leçon 1
View, Text, Image, ScrollView — les briques de base
Section 1
Step 1
React Native n'utilise pas de balises HTML. View ≈ div, Text ≈ p/span, Image ≈ img. Tout texte doit être dans un composant Text.
TutorialCard.tsx
1import {
2 View, Text, Image, TouchableOpacity, StyleSheet
3} from 'react-native';
4
5interface Props {
6 title: string;
7 level: string;
8 duration: number;
9 thumbnailUrl: string;
10 onPress: () => void;
11}
12
13export function TutorialCard({ title, level, duration, thumbnailUrl, onPress }: Props) {
14 return (
15 <TouchableOpacity style={styles.card} onPress={onPress} activeOpacity={0.7}>
16 <Image
17 source={{ uri: thumbnailUrl }}
18 style={styles.thumbnail}
19 resizeMode="cover"
20 />
21 <View style={styles.content}>
22 <Text style={styles.title} numberOfLines={2}>{title}</Text>
23 <View style={styles.meta}>
24 <View style={styles.levelBadge}>
25 <Text style={styles.levelText}>{level}</Text>
26 </View>
27 <Text style={styles.duration}>{duration} min</Text>
28 </View>
29 </View>
30 </TouchableOpacity>
31 );
32}
33
34// StyleSheet — équivalent CSS mais avec camelCase et valeurs numériques
35const styles = StyleSheet.create({
36 card: {
37 backgroundColor: '#fff',
38 borderRadius: 12,
39 overflow: 'hidden',
40 elevation: 3, // Android shadow
41 shadowColor: '#000', // iOS shadow
42 shadowOffset: { width: 0, height: 2 },
43 shadowOpacity: 0.1,
44 shadowRadius: 4,
45 },
46 thumbnail: {
47 width: '100%',
48 height: 160,
49 },
50 content: { padding: 12 },
51 title: { fontSize: 16, fontWeight: '600', color: '#1a1a1a' },
52 meta: { flexDirection: 'row', alignItems: 'center', marginTop: 8, gap: 8 },
53 levelBadge: { backgroundColor: '#e8f4ff', paddingHorizontal: 8,
54 paddingVertical: 2, borderRadius: 4 },
55 levelText: { fontSize: 12, color: '#007aff', fontWeight: '500' },
56 duration: { fontSize: 12, color: '#666' },
57});Step 2
FlatList est l'équivalent virtualisé de ul + map. Il ne rend que les éléments visibles à l'écran — essentiel pour les grandes listes.