Les Composants Fondamentaux de React Native et le JSX
Bienvenue dans ce module essentiel de notre cours sur le Développement Mobile Cross-Plateforme avec React Native : Créez des Applications iOS et Android Performantes. Aujourd'hui, nous allons plonger au cœur de React Native en explorant ses briques de construction fondamentales : les Composants et la syntaxe JSX. Comprendre ces concepts est absolument vital pour quiconque souhaite maîtriser le développement d'applications mobiles performantes et réactives avec React Native.
À la fin de cette leçon, vous aurez une compréhension solide de ce que sont les composants, comment ils gèrent leurs données via les props et le state, vous connaîtrez les composants intégrés les plus courants de React Native, et vous maîtriserez la syntaxe JSX qui permet de décrire l'interface utilisateur de manière déclarative.
1. Les Composants : Les Briques de Construction de l'UI
En React Native, comme en React, tout est un composant. Pensez aux composants comme à des pièces de LEGO : chacun a une fonction spécifique, peut être assemblé avec d'autres pour créer des structures plus grandes et plus complexes, et peut être réutilisé à l'infini. Un composant est une unité de code autonome et réutilisable qui décrit une partie de l'interface utilisateur.
1.1. Types de Composants
Historiquement, React et React Native ont eu deux types de composants, mais l'écosystème privilégie désormais un type en particulier :
1.1.1. Composants Fonctionnels (Function Components)
Introduits avec les Hooks de React 16.8, les composants fonctionnels sont la manière préférée et moderne de créer des composants. Ils sont de simples fonctions JavaScript qui reçoivent des props (propriétés) en argument et retournent des éléments React décrivant ce qui doit être affiché.
- Simplicité: Plus concis et plus faciles à lire.
- Performance: Souvent plus optimisés en interne par React.
- Hooks: Permettent d'ajouter des fonctionnalités d'état (
useState) et de cycle de vie (useEffect) à des composants fonctionnels, ce qui était auparavant l'apanage des composants de classe.
import React from 'react';
import { View, Text } from 'react-native';
// Un composant fonctionnel simple
const MonPremierComposant = () => {
return (
<View>
<Text>Bonjour, monde React Native !</Text>
</View>
);
};
export default MonPremierComposant;
Explication du code ci-dessus : MonPremierComposant est une fonction JavaScript qui retourne du JSX. Ce JSX décrit une View (un conteneur flexible) contenant un Text (pour afficher du texte). C'est la structure minimale d'un composant en React Native.
1.1.2. Composants de Classe (Class Components)
Moins utilisés pour les nouveaux développements, les composants de classe sont des classes JavaScript qui étendent React.Component. Ils possèdent des méthodes de cycle de vie et une gestion d'état interne via this.state. Bien qu'encore présents dans de nombreux codes legacy, les composants fonctionnels avec Hooks les ont largement supplantés pour leur clarté et leur simplicité.
1.2. Les Props (Propriétés) : Transmettre des Données
Les props sont des arguments que vous passez à vos composants. Elles permettent de faire communiquer les composants entre eux, généralement d'un composant parent vers un composant enfant.
- Lecture Seule: Les
propssont immuables. Un composant ne doit jamais modifier ses propresprops. Elles servent à configurer et personnaliser le comportement d'un composant depuis l'extérieur. - Passage de données: Elles peuvent être de n'importe quel type JavaScript (chaînes de caractères, nombres, booléens, tableaux, objets, fonctions, etc.).
Exemple de composant avec props :
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
const Greeting = ({ name }) => { // Le composant reçoit un objet "props", ici déstructuré pour extraire "name"
return (
<View style={styles.container}>
<Text style={styles.text}>Bonjour, {name} !</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
padding: 10,
backgroundColor: '#e8f5e9', // Vert clair
borderRadius: 8,
marginVertical: 5,
},
text: {
fontSize: 20,
fontWeight: 'bold',
color: '#2e7d32', // Vert foncé
},
});
export default Greeting;
Explication du code ci-dessus : Le composant Greeting accepte une prop name. Lorsque vous utilisez ce composant comme <Greeting name="Alice" />, la valeur "Alice" est passée et affichée. Les styles sont définis via StyleSheet.create et appliqués via la prop style.
1.3. Le State (État) : Gérer les Données Internes
Alors que les props permettent de passer des données de l'extérieur vers un composant, le state (état) permet à un composant de gérer ses propres données internes qui peuvent changer au fil du temps.
- Données Muables: Le
stateest la seule exception où un composant peut modifier ses propres données. - Déclenchement de re-rendu: Lorsque le
stated'un composant change, React Native re-rend le composant et ses enfants pour refléter ces changements dans l'interface utilisateur. useStateHook: Dans les composants fonctionnels, lestateest géré via le HookuseState.
Exemple de composant avec state :
import React, { useState } from 'react'; // Importation du Hook useState
import { View, Text, Button, StyleSheet } from 'react-native';
const Counter = () => {
// Déclaration d'une variable d'état 'count' et de sa fonction de mise à jour 'setCount'
// La valeur initiale de 'count' est 0.
const [count, setCount] = useState(0);
const increment = () => {
setCount(prevCount => prevCount + 1); // Mise à jour de l'état : incrémente le compteur
};
const decrement = () => {
setCount(prevCount => prevCount - 1); // Mise à jour de l'état : décrémente le compteur
};
return (
<View style={styles.container}>
<Text style={styles.countText}>Compteur : {count}</Text>
<View style={styles.buttonContainer}>
<Button title="Moins" onPress={decrement} color="#e74c3c" /> {/* Bouton "Moins" */}
<Button title="Plus" onPress={increment} color="#2ecc71" /> {/* Bouton "Plus" */}
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
alignItems: 'center',
padding: 20,
backgroundColor: '#fff',
borderRadius: 10,
elevation: 3, // Ombre pour Android
shadowColor: '#000', // Ombre pour iOS
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 3,
},
countText: {
fontSize: 32,
marginBottom: 20,
fontWeight: 'bold',
color: '#2c3e50',
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'space-around',
width: '80%',
},
});
export default Counter;
Explication du code ci-dessus : Le composant Counter utilise useState(0) pour créer une variable d'état count initialisée à 0. Les fonctions increment et decrement appellent setCount pour modifier cette variable. Chaque appel à setCount déclenche un re-rendu du composant, mettant à jour la valeur affichée du compteur.
2. Les Composants Intégrés (Core Components) de React Native
React Native ne vous demande pas de réinventer la roue. Il fournit un ensemble de composants prêts à l'emploi qui sont les équivalents abstraits des éléments d'interface utilisateur natifs de iOS et Android. Ces composants sont le fondement de toute application React Native.
Voici quelques-uns des plus fondamentaux :
2.1. View
- Le conteneur universel.
Viewest le composant le plus fondamental. Il est utilisé pour créer des mises en page (layouts) avecflexbox, gérer les styles, et servir de conteneur pour d'autres composants. - Analogie web: C'est l'équivalent d'une
<div>en HTML. - Propriétés courantes:
style(pour le CSS-in-JS),onPress(pour rendre la vue cliquable, utile pour créer des boutons personnalisés).
2.2. Text
- Pour afficher du texte. C'est le seul moyen d'afficher du texte dans votre application. Tout le texte que vous voulez afficher doit être imbriqué à l'intérieur d'un composant
Text. - Propriétés courantes:
style(pour la taille de la police, la couleur, le poids, etc.),numberOfLines(pour limiter le texte sur un certain nombre de lignes).
2.3. Image
- Pour afficher des images. Permet d'intégrer des images depuis le bundle de l'application (locale) ou une URL distante.
- Propriétés courantes:
source(un objet{ uri: '...' }pour une image distante ourequire('./path/to/image.png')pour une locale),style(pour la taille, le redimensionnementresizeMode).
2.4. Button
- Un bouton simple. Fournit un composant de bouton basique et très stylisé par défaut pour la plateforme native.
- Propriétés courantes:
title(le texte affiché sur le bouton),onPress(la fonction appelée lorsque le bouton est pressé),color(la couleur du bouton). Pour un contrôle de style plus fin, vous utiliserez souventTouchableOpacityouPressableavecViewetText.
2.5. TextInput
- Pour la saisie de texte. Permet aux utilisateurs de saisir du texte via le clavier du système.
- Propriétés courantes:
value(la valeur actuelle du texte),onChangeText(fonction appelée lorsque le texte change),placeholder(texte indicatif),keyboardType(type de clavier à afficher).
2.6. Autres Composants Utiles (mention rapide)
ScrollView: Pour des contenus défilants.FlatList/SectionList: Pour afficher de longues listes de données de manière performante.ActivityIndicator: Pour afficher un indicateur de chargement.
3. Le JSX (JavaScript XML) : Décrire l'Interface Utilisateur
Le JSX est une extension de syntaxe pour JavaScript. Il a l'air un peu comme du HTML dans votre code JavaScript, mais il est beaucoup plus puissant. React Native utilise JSX pour décrire à quoi doit ressembler l'interface utilisateur.
3.1. Qu'est-ce que le JSX et pourquoi l'utiliser ?
- Syntaxe Déclarative: Au lieu de manipuler directement le DOM (comme avec JavaScript pur), vous décrivez ce que vous voulez voir à l'écran, et React Native se charge de la manière de le rendre.
- Lisibilité: Le JSX est plus lisible et intuitif pour décrire des structures d'UI complexes que de simples appels de fonctions JavaScript.
- Puissance de JavaScript: Il vous permet d'écrire du JavaScript directement dans votre balisage, fusionnant ainsi la logique et la présentation.
3.2. Règles Fondamentales du JSX
Pour écrire du JSX correctement, il y a quelques règles à respecter :
3.2.1. Retourner un Seul Élément Racine
Chaque composant doit retourner un seul élément parent. Si vous voulez retourner plusieurs éléments adjacents, vous devez les envelopper dans un conteneur commun, comme un <View>, ou utiliser un Fragment.
// Incorrect (si vous essayez de retourner ces deux Text directement)
/*
return (
<Text>Bonjour</Text>
<Text>Monde</Text>
);
*/
// Correct avec View
return (
<View>
<Text>Bonjour</Text>
<Text>Monde</Text>
</View>
);
// Correct avec React.Fragment ou sa syntaxe raccourcie (<>)
import React from 'react';
// ...
return (
<> {/* Fragment vide */}
<Text>Bonjour</Text>
<Text>Monde</Text>
</>
);
3.2.2. Les Balises Doivent Être Fermées
Toutes les balises doivent être explicitement fermées. Les balises auto-fermantes (comme <Image>, <TextInput>) doivent se terminer par /.
<View></View> // Balise ouvrante et fermante
<Text>Mon texte</Text> // Balise ouvrante et fermante avec du contenu
<Image source={{ uri: '...' }} /> // Balise auto-fermante
3.2.3. Propriétés en CamelCase
Les propriétés des composants (ce qui était les attributs en HTML) sont écrites en camelCase en JSX.
onPressau lieu deonclickonChangeTextau lieu deonchangenumberOfLinesau lieu denumber-of-lines
3.2.4. Expressions JavaScript dans le JSX ({})
C'est là que le JSX devient vraiment puissant. Vous pouvez intégrer n'importe quelle expression JavaScript dans votre JSX en l'enveloppant avec des accolades {}.
-
Variables:
const userName = "ChatGPT"; return <Text>Bienvenue, {userName}!</Text>; -
Appels de fonctions:
const formatName = (firstName, lastName) => `${firstName} ${lastName}`; return <Text>{formatName("Jane", "Doe")}</Text>; -
Logique conditionnelle (Opérateur Ternaire ou
&&):const isLoggedIn = true; return ( <View> {isLoggedIn ? <Text>Connecté</Text> : <Text>Déconnecté</Text>} </View> ); // Afficher un élément seulement si une condition est vraie const showWarning = true; return ( <View> {showWarning && <Text style={{ color: 'red' }}>Attention !</Text>} </View> ); -
Rendu de listes (
map): Pour afficher des listes d'éléments, vous utiliserez souvent la méthodemapsur un tableau. Chaque élément de la liste doit avoir une propkeyunique.const fruits = ['Pomme', 'Banane', 'Cerise']; return ( <View> {fruits.map((fruit, index) => ( <Text key={index}>{fruit}</Text> // 'key' est essentiel pour la performance et la stabilité ))} </View> );
3.3. Style en React Native (via JSX)
En React Native, le style n'est pas appliqué via des fichiers CSS externes, mais directement dans votre JavaScript via la prop style de chaque composant.
- Objets JavaScript: Les styles sont des objets JavaScript, avec des propriétés en
camelCase(ex:backgroundColor,fontSize). StyleSheet.create: Pour une meilleure organisation et performance, il est recommandé d'utiliserStyleSheet.create.
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
const StyledComponent = () => {
return (
<View style={styles.container}>
<Text style={styles.title}>Composant Stylisé</Text>
<Text style={styles.description}>Ceci est un exemple de style en React Native.</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
backgroundColor: '#ffe0b2', // Orange clair
padding: 20,
borderRadius: 10,
margin: 10,
alignItems: 'center',
},
title: {
fontSize: 24,
fontWeight: 'bold',
color: '#e65100', // Orange foncé
marginBottom: 10,
},
description: {
fontSize: 16,
color: '#bf360c', // Marron foncé
textAlign: 'center',
},
});
export default StyledComponent;
Explication du code ci-dessus : Les styles sont définis dans un objet styles créé avec StyleSheet.create. Ces styles sont ensuite appliqués aux composants View et Text via la prop style. Cela rend le code plus propre et les styles plus réutilisables.
Conclusion
Félicitations ! Vous avez maintenant une compréhension approfondie des blocs de construction fondamentaux de React Native. Vous savez que les composants sont les unités réutilisables qui composent votre interface utilisateur, gérant leurs données via les props (pour la configuration externe et la communication descendante) et le state (pour les données internes et mutables). Vous êtes également familier avec les composants intégrés (Core Components) tels que View, Text, Image, Button et TextInput, qui mappent directement aux éléments natifs de l'interface.
Enfin, vous maîtrisez les bases du JSX, la syntaxe déclarative qui vous permet d'écrire du HTML-like dans votre JavaScript, en intégrant dynamiquement des expressions JavaScript. Cette combinaison puissante de composants et de JSX est la pierre angulaire de toute application React Native, vous permettant de construire des interfaces utilisateur complexes et interactives de manière efficace et maintenable.
Dans les prochaines leçons, nous explorerons comment organiser ces composants, gérer la navigation entre eux et interagir avec des services externes pour créer des applications mobiles complètes et performantes. Gardez à l'esprit ces fondations, car elles seront la base de tout ce que vous construirez.