Cours JavaScript et React · Module 1: Bases de React

Ton premier composant

6 min de lecture
Dans cette leçon10

Au cœur de React se trouvent les composants : des blocs de code autonomes et réutilisables qui encapsulent du HTML, du CSS et du JavaScript. Les composants sont comme des briques LEGO à partir desquelles tu construis ton interface utilisateur. Dans cette leçon, nous allons créer notre premier composant React et comprendre sa structure de base.

Qu'est-ce qu'un composant React ?

Un composant React est une fonction JavaScript (ou une classe) qui renvoie un élément React (JSX). Les composants te permettent de découper l'interface utilisateur en parties indépendantes et réutilisables, et de réfléchir à chaque partie séparément.

Créer ton premier composant fonctionnel

Commençons par créer un simple composant fonctionnel. Un composant fonctionnel est une fonction JavaScript ordinaire qui renvoie du JSX :

1// Fichier : WelcomeMessage.jsx
2import React from 'react';
3
4function WelcomeMessage() {
5  return (
6    <div className="welcome-container">
7      <h1>Welcome to the world of React!</h1>
8      <p>This is your first component.</p>
9    </div>
10  );
11}
12
13export default WelcomeMessage;

Éléments clés de ce composant :

  1. Import de React - import React from 'react'; (depuis React 17 ce n'est plus nécessaire : la nouvelle transformation JSX utilisée par Vite ajoute elle-même le code requis, c'est pourquoi App.jsx du modèle Vite ne contient pas cet import ; tu le verras cependant dans du code plus ancien et dans cette leçon)
  2. Déclaration de la fonction - function WelcomeMessage() {...}
  3. Retour avec du JSX - La fonction renvoie du JSX qui définit la structure du composant
  4. Export - export default WelcomeMessage; permet d'importer le composant dans d'autres fichiers

JSX - qu'est-ce que c'est exactement ?

JSX (JavaScript XML) est une extension de syntaxe pour JavaScript qui te permet d'écrire du code ressemblant à du HTML directement dans JavaScript. Sans JSX, créer des éléments React serait bien plus complexe :

1// Avec JSX
2function WelcomeMessage() {
3  return (
4    <div className="welcome-container">
5      <h1>Welcome to the world of React!</h1>
6      <p>This is your first component.</p>
7    </div>
8  );
9}
10
11// Sans JSX (voici ce en quoi React transforme réellement le JSX)
12function WelcomeMessage() {
13  return React.createElement(
14    'div',
15    { className: 'welcome-container' },
16    React.createElement('h1', null, 'Welcome to the world of React!'),
17    React.createElement('p', null, 'This is your first component.')
18  );
19}

Comme tu peux le voir, JSX rend le code beaucoup plus lisible et ressemble à du HTML, que la plupart des développeurs connaissent bien.

Les règles du JSX

JSX ressemble à du HTML mais comporte plusieurs différences importantes :

  1. className au lieu de class - Comme « class » est un mot-clé réservé en JavaScript, en JSX nous utilisons className pour définir les classes CSS
  2. Les attributs utilisent le camelCase - Les attributs HTML comme onclick s'écrivent onClick en JSX
  3. Balises auto-fermantes - Les balises comme <img> doivent être fermées : <img />
  4. Expressions JavaScript dans le JSX - Tu peux utiliser des expressions JavaScript entre accolades : {expression}

Utiliser les propriétés (props)

Les composants peuvent recevoir des données via des propriétés (props). Les props sont un moyen de transmettre des données d'un composant parent à un composant enfant :

1// Fichier : WelcomeMessage.jsx
2function WelcomeMessage(props) {
3  return (
4    <div className="welcome-container">
5      <h1>Welcome, {props.name}!</h1>
6      <p>{props.message}</p>
7    </div>
8  );
9}
10
11export default WelcomeMessage;
12
13// Utilisation du composant
14<WelcomeMessage name="Cosmonaut" message="Ready for a journey through the React galaxy?" />

Nous pouvons aussi utiliser la déstructuration des props, ce qui rend le code plus lisible :

1function WelcomeMessage({ name, message }) {
2  return (
3    <div className="welcome-container">
4      <h1>Welcome, {name}!</h1>
5      <p>{message}</p>
6    </div>
7  );
8}

Rendu conditionnel

L'une des forces des composants React est la capacité d'afficher différents éléments selon certaines conditions :

1function WelcomeMessage({ name, isLoggedIn }) {
2  return (
3    <div className="welcome-container">
4      {isLoggedIn ? (
5        <h1>Welcome back, {name}!</h1>
6      ) : (
7        <h1>Welcome, guest! Log in to continue.</h1>
8      )}
9    </div>
10  );
11}

Rendu de listes

Les composants React sont parfaits pour afficher des listes de données :

1function AstronautList({ astronauts }) {
2  return (
3    <div className="astronaut-list">
4      <h2>Space mission crew:</h2>
5      <ul>
6        {astronauts.map(astronaut => (
7          <li key={astronaut.id}>
8            {astronaut.name} - {astronaut.role}
9          </li>
10        ))}
11      </ul>
12    </div>
13  );
14}
15
16// Utilisation
17const crewMembers = [
18  { id: 1, name: "John Smith", role: "Captain" },
19  { id: 2, name: "Anna Green", role: "Scientist" },
20  { id: 3, name: "Thomas Wright", role: "Engineer" }
21];
22
23<AstronautList astronauts={crewMembers} />

Remarque l'attribut key - il est requis lors du rendu de listes afin que React puisse mettre à jour efficacement le DOM lorsque la liste change.

Styliser les composants

Il existe plusieurs façons de styliser les composants React :

1. Feuille de style CSS externe

1// WelcomeMessage.css
2.welcome-container {
3  padding: 20px;
4  border-radius: 8px;
5  background-color: #f5f5f5;
6  text-align: center;
7}
8
9// WelcomeMessage.jsx
10import React from 'react';
11import './WelcomeMessage.css';
12
13function WelcomeMessage({ name }) {
14  return (
15    <div className="welcome-container">
16      <h1>Welcome, {name}!</h1>
17    </div>
18  );
19}

2. Styles inline

1function WelcomeMessage({ name }) {
2  const styles = {
3    container: {
4      padding: '20px',
5      borderRadius: '8px',
6      backgroundColor: '#f5f5f5',
7      textAlign: 'center'
8    },
9    heading: {
10      color: '#333',
11      fontSize: '24px'
12    }
13  };
14
15  return (
16    <div style={styles.container}>
17      <h1 style={styles.heading}>Welcome, {name}!</h1>
18    </div>
19  );
20}

3. CSS Modules

1// WelcomeMessage.module.css
2.container {
3  padding: 20px;
4  border-radius: 8px;
5  background-color: #f5f5f5;
6  text-align: center;
7}
8
9// WelcomeMessage.jsx
10import React from 'react';
11import styles from './WelcomeMessage.module.css';
12
13function WelcomeMessage({ name }) {
14  return (
15    <div className={styles.container}>
16      <h1>Welcome, {name}!</h1>
17    </div>
18  );
19}

Composition de composants

L'un des plus grands avantages de React est la capacité de composer de plus grandes interfaces à partir de composants plus petits :

1// Button.jsx
2function Button({ onClick, children, color = 'blue' }) {
3  return (
4    <button
5      onClick={onClick}
6      style={{
7        backgroundColor: color,
8        color: 'white',
9        padding: '10px 15px',
10        border: 'none',
11        borderRadius: '4px',
12        cursor: 'pointer'
13      }}
14    >
15      {children}
16    </button>
17  );
18}

Résumé

Dans cette leçon, nous avons appris :

  • Ce que sont les composants React et comment les créer
  • Les bases du JSX et ses règles
  • Comment utiliser les props pour transmettre des données
  • Le rendu conditionnel et les listes
  • Différentes méthodes de stylisation des composants
  • La composition de composants pour construire de plus grandes interfaces

Les composants sont l'élément fondamental de React, et comprendre leur fonctionnement est essentiel au développement efficace d'applications React. Dans les modules suivants, nous approfondirons des concepts avancés comme l'état, le cycle de vie des composants et les hooks.

Code de cette leçon : App.jsx
1import React, { useState } from 'react';
2
3// Exemple de composant fonctionnel
4function SpaceshipCard({ name, type, speed, crew, status }) {
5  const statusColors = {
6    active: '#4caf50',
7    maintenance: '#ff9800',
8    docked: '#2196f3'
9  };
10
11  return (
12    <div style={{
13      backgroundColor: '#1a1a2e',
14      border: '2px solid #16213e',
15      borderRadius: '12px',
16      padding: '20px',
17      color: 'white',
18      transition: 'transform 0.2s',
19    }}>
20      <div style={{
21        display: 'flex',
22        justifyContent: 'space-between',
23        alignItems: 'center',
24        marginBottom: '15px'
25      }}>
26        <h3 style={{ margin: 0, color: '#00d4ff' }}>{name}</h3>
27        <span style={{
28          padding: '4px 12px',
29          backgroundColor: statusColors[status],
30          borderRadius: '20px',
31          fontSize: '12px',
32          fontWeight: 'bold'
33        }}>
34          {status.toUpperCase()}
35        </span>
36      </div>
37      <div style={{ display: 'grid', gap: '10px' }}>
38        <div style={{ display: 'flex', justifyContent: 'space-between' }}>
39          <span style={{ color: '#888' }}>Type :</span>
40          <span>{type}</span>
41        </div>
42        <div style={{ display: 'flex', justifyContent: 'space-between' }}>
43          <span style={{ color: '#888' }}>Vitesse :</span>
44          <span>{speed} km/s</span>
45        </div>
46        <div style={{ display: 'flex', justifyContent: 'space-between' }}>
47          <span style={{ color: '#888' }}>Équipage :</span>
48          <span>{crew} personnes</span>
49        </div>
50      </div>
51    </div>
52  );
53}
54
55// Composant avec props et children
56function SpaceSection({ title, children }) {
57  return (
58    <section style={{
59      backgroundColor: '#0f0f23',
60      borderRadius: '16px',
61      padding: '25px',
62      marginBottom: '20px'
63    }}>
64      <h2 style={{
65        color: '#00d4ff',
66        borderBottom: '2px solid #16213e',
67        paddingBottom: '10px',
68        marginTop: 0
69      }}>
70        {title}
71      </h2>
72      {children}
73    </section>
74  );
75}
76
77// Composant principal de l'application
78export default function App() {
79  const [selectedShip, setSelectedShip] = useState(null);
80
81  const spaceships = [
82    { id: 1, name: 'Aurora', type: 'Vaisseau de recherche', speed: 50000, crew: 12, status: 'active' },
83    { id: 2, name: 'Nebula', type: 'Vaisseau de transport', speed: 35000, crew: 8, status: 'docked' },
84    { id: 3, name: 'Phoenix', type: 'Vaisseau de combat', speed: 75000, crew: 25, status: 'maintenance' },
85    { id: 4, name: 'Odyssey', type: 'Vaisseau de colonisation', speed: 20000, crew: 500, status: 'active' },
86  ];
87
88  return (
89    <div style={{
90      fontFamily: 'Arial, sans-serif',
91      backgroundColor: '#0a0a1a',
92      minHeight: '100vh',
93      padding: '20px',
94      color: 'white'
95    }}>
96      <header style={{
97        textAlign: 'center',
98        marginBottom: '30px',
99        padding: '30px',
100        background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
101        borderRadius: '16px'
102      }}>
103        <h1 style={{ margin: 0, fontSize: '2.5rem' }}>Flotte spatiale</h1>
104        <p style={{ margin: '10px 0 0 0', opacity: 0.9 }}>
105          Gère des vaisseaux spatiaux à l'aide de composants React
106        </p>
107      </header>
108
109      <SpaceSection title="Vaisseaux dans le système">
110        <div style={{
111          display: 'grid',
112          gridTemplateColumns: 'repeat(auto-fit, minmax(280px, 1fr))',
113          gap: '20px'
114        }}>
115          {spaceships.map(ship => (
116            <div key={ship.id} onClick={() => setSelectedShip(ship)}>
117              <SpaceshipCard {...ship} />
118            </div>
119          ))}
120        </div>
121      </SpaceSection>
122
123      {selectedShip && (
124        <SpaceSection title="Détails du vaisseau sélectionné">
125          <div style={{
126            backgroundColor: '#1a1a2e',
127            padding: '20px',
128            borderRadius: '12px'
129          }}>
130            <h3 style={{ color: '#00d4ff', marginTop: 0 }}>{selectedShip.name}</h3>
131            <p>Ce vaisseau de type « {selectedShip.type} » peut accueillir {selectedShip.crew} membres d'équipage.</p>
132            <p>Vitesse maximale : {selectedShip.speed.toLocaleString()} km/s</p>
133            <button
134              onClick={() => setSelectedShip(null)}
135              style={{
136                padding: '10px 20px',
137                backgroundColor: '#f44336',
138                color: 'white',
139                border: 'none',
140                borderRadius: '8px',
141                cursor: 'pointer'
142              }}
143            >
144              Fermer
145            </button>
146          </div>
147        </SpaceSection>
148      )}
149
150      <div style={{
151        backgroundColor: '#1a1a2e',
152        padding: '20px',
153        borderRadius: '12px',
154        marginTop: '20px'
155      }}>
156        <h3 style={{ color: '#4caf50', marginTop: 0 }}>Concepts clés des composants :</h3>
157        <ul style={{ lineHeight: '1.8', color: '#ccc' }}>
158          <li><strong>Props</strong> - données transmises au composant (name, type, speed...)</li>
159          <li><strong>Children</strong> - contenu entre les balises du composant</li>
160          <li><strong>Composition</strong> - les composants peuvent contenir d'autres composants</li>
161          <li><strong>Réutilisabilité</strong> - SpaceshipCard utilisé plusieurs fois avec des données différentes</li>
162        </ul>
163      </div>
164    </div>
165  );
166}

Tu as repéré une erreur dans cette leçon ?

Teste tes connaissances

Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.

  1. 1. Par quelle lettre doit commencer le nom d'un composant pour que JSX traite <Nom /> comme un composant et non comme une balise HTML ?

Tâches pratiques dans le jeu

  • Tri horizontal

    Ordonne la syntaxe correcte d'export par défaut d'un composant React :

  • Éditeur de code

    Crée un composant StationModule : une fonction qui prend des props et renvoie un <div> avec le nom du module (props.name) et le statut (props.status). Exemple : 'Module : Moteurs | Statut : En ligne'

  • Clique dans l'ordre

    Ordonne la syntaxe d'un composant fonctionnel :

  • Éditeur de code

    Crée une SpaceCapsule qui accepte { missionName, crew, destination }. Affiche : 'Mission : [missionName]', 'Équipage : [crew] membres', 'Destination : [destination]'. Utilise la déstructuration des props.

  • Tri vertical

    Ordonne le processus de création d'un composant React :

  • Éditeur de code

    Crée un composant Navigation dans un fichier séparé (par ex. Navigation.jsx) et exporte-le, puis importe-le dans App.jsx et affiche-le dans le composant principal Spaceship.

Articles utiles