Le modèle mental de React
C'est le module clé du guide. Si React te semble encore flou, ce n'est presque jamais
un problème de syntaxe : c'est qu'il te manque le modèle mental, la bonne image dans la tête.
Une fois que tu l'as, tout le reste — useState, les props, les listes, les optimisations —
arrête de ressembler à de la magie et devient une suite de conséquences logiques. On va prendre le
temps. Beaucoup de texte, beaucoup d'analogies, peu de code : c'est voulu. L'idée à graver est
simple : un composant est une fonction qui décrit l'écran à partir de tes données, et React
se charge de fabriquer cet écran à ta place.
Imagine une machine à fabriquer des écrans. Tu ne touches jamais l'écran toi-même. Tu donnes des données à la machine (le score, le nom de l'utilisateur, la liste des exercices) et tu lui remets un plan qui dit « voilà à quoi l'écran doit ressembler pour ces données ». La machine lit le plan et dessine. Quand les données changent, tu ne corriges pas le dessin au feutre : tu redonnes un plan à jour, et la machine se débrouille pour ne remplacer que ce qui a réellement changé. Cette machine, c'est React. Le « plan », c'est le JSX. Et le moment où React relit ton plan s'appelle le re-render. Garde cette image : on va la décortiquer morceau par morceau pendant tout le module.
1. Déclaratif vs impératif : la bascule mentale
Avant React, on construisait les interfaces de façon impérative. « Impératif » veut dire : tu donnes une suite d'ordres, étape par étape, en manipulant l'écran à la main. Tu trouves le bouton, tu changes sa couleur, tu trouves le compteur, tu lis l'ancien nombre, tu ajoutes un, tu réécris le texte, tu trouves le message d'erreur, tu le caches… Toi, le programmeur, tu es responsable de chaque transition entre deux états de l'écran. Tu dois te souvenir de ce qui était affiché avant pour savoir quoi modifier maintenant.
React renverse complètement cette logique : il est déclaratif. « Déclaratif » veut dire : tu ne donnes pas la suite d'étapes, tu décris le résultat voulu. Tu dis « pour ces données-là, l'écran doit ressembler à ça », et c'est React qui calcule tout seul la suite d'ordres à exécuter pour passer de l'écran actuel à l'écran décrit. Tu décris le quoi ; React s'occupe du comment. Tu ne manipules plus jamais l'écran à la main.
Cuisiner soi-même, c'est impératif : tu allumes le feu, tu coupes l'oignon, tu le fais revenir, tu surveilles, tu retournes la viande au bon moment… tu contrôles chaque geste, et si tu en rates un, le plat est raté. Commander au restaurant, c'est déclaratif : tu dis au serveur « je veux un steak frites, cuisson à point ». Tu décris le résultat. Tu ne dis pas au cuisinier à quelle température régler la plaque ni combien de minutes par face. La cuisine (React) traduit ta description en gestes concrets. Et si tu changes d'avis — « finalement, salade au lieu des frites » — tu redonnes ta commande complète à jour, tu ne cours pas en cuisine retirer les frites de l'assiette toi-même.
Cette bascule est inconfortable au début parce qu'on a l'instinct impératif : « l'utilisateur a cliqué, donc je dois aller changer ce texte ». En React, on réapprend à penser autrement : « l'utilisateur a cliqué, donc je change une donnée ; React relira ma description et mettra le texte à jour pour moi ». Tu ne touches jamais le texte. Tu touches la donnée. Toute la suite du guide repose sur ce réflexe : on agit sur les données, jamais sur l'écran.
| Façon de penser | Impératif (l'ancien monde) | Déclaratif (React) |
|---|---|---|
| Ce que tu écris | Les étapes pour modifier l'écran | Une description de l'écran voulu |
| Qui gère les transitions | Toi, à la main | React, automatiquement |
| Ce que tu modifies | Les éléments à l'écran directement | Tes données (état, props) |
| Analogie | Cuisiner soi-même | Commander au restaurant |
| Risque principal | Oublier une transition → écran incohérent | Quasi nul : l'écran suit toujours les données |
2. UI = fonction(état) : l'équation fondatrice
On la résume souvent par une formule : UI = fonction(état). Lis-la comme une vraie
équation de maths. « UI », c'est l'interface, ce que l'utilisateur voit. « état » (ou plus largement
tes données), c'est l'entrée. Et la fonction, c'est ton composant. Autrement dit : l'interface est
le résultat de tes données à un instant T. Donne les mêmes données, tu obtiens le même écran.
Toujours. C'est déterministe, comme 2 + 2 fait toujours 4.
La conséquence est énorme et libératrice : tu n'as plus à te demander « dans quel état est l'écran en ce moment ? ». L'écran n'a pas de mémoire propre, pas de vie cachée. Il n'est que le reflet de tes données. Si tu veux savoir ce qui est affiché, tu regardes les données. Si tu veux changer ce qui est affiché, tu changes les données — et l'interface suit, automatiquement. L'écran est un miroir ; tu ne maquilles pas le reflet, tu maquilles le visage.
Quand on écrit UI = fonction(état), le mot « état » englobe toutes les données qui entrent
dans le composant : les props (les données que le parent te donne) et l'état
local (les données que le composant garde pour lui, via useState, qu'on verra dans
le module « useState & useEffect »). Pour l'instant, retiens juste : entrée = données,
sortie = écran.
Voici la forme la plus simple possible d'un composant, juste pour ancrer l'équation. Repère bien
l'aller-retour : des données entrent par les paramètres, une description sort par le return.
// `props` = les données qui ENTRENT dans le composant (ses réglages).
// Le composant RETOURNE une description de ce qu'on voit (du JSX).
function Greeting(props) {
return <Text>Bonjour {props.name}</Text>;
}
// Ailleurs, on l'utilise comme une balise, en passant les données :
<Greeting name="Patrick" /> // décrit : Bonjour Patrick
Données en entrée → description en sortie. Un composant ne « fait » fondamentalement rien d'autre : il calcule à quoi l'écran doit ressembler pour les données qu'on lui donne. Ce n'est pas un objet qui vit et se modifie ; c'est une fonction qu'on rappelle.
3. Un composant = une fonction qui retourne du JSX
Maintenant qu'on a l'équation, regardons un vrai composant de Halterofit. C'est le composant
Text, celui que toute l'app utilise pour afficher du texte stylé. Ne te laisse pas
intimider par les types ou les détails : on cherche uniquement à reconnaître le squelette « fonction
qui reçoit des données et retourne une description ».
function Text({
className, // ┐ on "déballe" les props directement
asChild = false, // │ dans les paramètres (= destructuration).
variant = 'default', // ┘ `= 'default'` est la valeur par défaut.
...props // le reste des props, regroupé d'un coup
}) {
// ... un peu de logique interne (on la verra dans
// le module « useState & useEffect ») ...
// RETOURNE le JSX : un composant texte, avec des classes de
// style calculées et toutes les autres props transmises.
return (
<Component
className={cn(textVariants({ variant }), textClass, className)}
{...props}
/>
);
}
Exactement le même squelette que Greeting : des données en paramètres, du JSX en retour.
La syntaxe { className, variant = 'default' } est juste une façon compacte de dire
« extrais-moi ces props nommées, avec ces valeurs par défaut si elles manquent ». Tout le reste n'est
que décoration autour de ce squelette.
Ce Text est utilisé des centaines de fois dans l'app. Chaque fois, c'est la même
fonction qui est appelée avec des props différentes — variant="h1" pour un titre,
variant="muted" pour une légende grise, etc. Une seule définition, mille usages. C'est
toute la puissance de « composant = fonction » : tu écris la recette une fois, tu la rappelles avec
des ingrédients différents partout.
Dans le JSX, { ... } veut dire « ici, insère le résultat de ce JavaScript ».
{props.name} insère une valeur, className={cn(...)} insère le résultat
d'un appel de fonction. Vois le JSX comme du HTML avec des trous qu'on remplit avec du JS.
Les trous, ce sont les accolades.
4. Le JSX, vraiment : du sucre pour des appels de fonction
Le JSX ressemble à du HTML, mais ce n'est pas du HTML, et ce n'est même pas vraiment de l'écran. C'est
du sucre syntaxique : une écriture plus jolie pour quelque chose de plus brut en
dessous. Sous le capot, chaque balise JSX est transformée par l'outillage (le compilateur, voir le
module sur l'outillage) en un simple appel de fonction. Conceptuellement,
<Text>Bonjour</Text> devient un appel du genre
React.createElement(Text, null, 'Bonjour').
// Ce que TU écris (agréable à lire) :
<Text variant="h1">Halterofit</Text>
// Ce que ça DEVIENT, conceptuellement (un appel de fonction) :
React.createElement(Text, { variant: 'h1' }, 'Halterofit')
Le JSX n'est qu'une écriture confortable. En dessous, ce sont des appels de fonction qui produisent des objets JavaScript ordinaires.
Cette transformation a une conséquence capitale qu'il faut bien intégrer : le résultat du JSX
n'est pas l'écran, c'est un objet en mémoire. React.createElement ne dessine
rien. Il renvoie un petit objet JavaScript qui décrit un élément : « un Text,
avec la prop variant: 'h1', contenant le texte "Halterofit" ». Cet objet n'a aucune
existence à l'écran. C'est une fiche descriptive, une note de service.
Et comme les composants s'imbriquent les uns dans les autres — un écran contient une vue, qui contient des textes et des boutons, qui contiennent eux-mêmes des choses — le JSX d'un composant décrit en réalité tout un arbre d'éléments. Pas l'écran réel : un arbre d'objets en mémoire qui dit à quoi l'écran devrait ressembler. C'est ce point qui débloque tout le reste du module : quand ton composant « retourne du JSX », il retourne une description sous forme d'arbre, pas des pixels.
Le JSX est un plan d'architecte, pas la maison. Le plan décrit les pièces, leur taille, leur agencement. Tu peux le redessiner mille fois sur papier sans qu'un seul mur ne bouge. C'est seulement quand on confie le plan aux ouvriers (React, à la phase de « commit » qu'on voit juste après) que des murs réels apparaissent ou se déplacent. Ton composant produit des plans ; React construit la maison.
5. Les deux phases : render puis commit
Quand quelque chose change, React travaille en deux temps bien distincts. Comprendre cette séparation dissout une grande partie du flou autour de React.
Phase 1 — le « render ». React appelle tes fonctions-composants. Chacune retourne son JSX, c'est-à-dire son arbre d'éléments décrivant l'écran voulu. React assemble tous ces petits arbres en un grand arbre complet : la photo de « voilà à quoi l'écran devrait ressembler maintenant ». Cette phase se passe entièrement en mémoire. Rien n'apparaît encore à l'écran. C'est du calcul pur : React fait tourner tes fonctions et obtient une description. On appelle souvent cet arbre en mémoire le Virtual DOM (« DOM virtuel ») — une maquette légère de l'interface, dans la mémoire, qu'on peut produire et comparer très vite parce que ce ne sont que des objets JavaScript.
Phase 2 — le « commit ». React a maintenant deux descriptions : l'ancienne (ce qui est déjà affiché) et la nouvelle (ce qui vient d'être calculé). Il les compare pour repérer précisément ce qui a changé — cette comparaison s'appelle le diff (« réconciliation » dans le vocabulaire React). Puis il applique uniquement les différences à l'écran réel. Si seul un nombre est passé de 9 à 10, React ne touche qu'à ce nombre. Le reste de l'écran ne bouge pas d'un pixel.
Imagine deux photos « avant / après » de ta cuisine. Plutôt que de tout casser et tout reconstruire, tu superposes les deux photos et tu cherches les différences : « ah, la tasse a bougé, et le voyant est passé au vert ». Tu ne corriges que ça. React fait pareil : il superpose l'ancien arbre et le nouveau, repère les différences, et ne modifie l'écran réel que là où c'est nécessaire. C'est pour ça que React est rapide : toucher l'écran réel coûte cher, comparer des objets en mémoire coûte peu. React fait le maximum de travail dans la maquette gratuite, et le minimum sur l'écran réel.
Cette séparation render / commit éclaire beaucoup de comportements de React. Par exemple, ta fonction de rendu peut être appelée plusieurs fois « pour rien » (juste pour calculer un arbre), tant que le commit, lui, n'applique que le strict nécessaire. C'est aussi pourquoi on insiste, dans le module « useState & useEffect », pour que ton rendu reste pur : pendant la phase de render, tu te contentes de décrire ; tu ne déclenches pas d'effets de bord (pas d'appel réseau, pas de modification directe de l'écran). Décrire d'abord, agir ensuite.
6. Le flux de données unidirectionnel
React impose une règle de circulation très stricte, et c'est une bénédiction : les données circulent dans un seul sens. On parle de flux unidirectionnel. Concrètement :
- Les données descendent : un composant parent passe des données à ses enfants via les props. Comme l'eau d'une cascade, ça coule du haut (le parent) vers le bas (les enfants), jamais l'inverse.
- Les événements remontent : quand un enfant veut signaler quelque chose (« on m'a cliqué », « le texte a changé »), il ne modifie pas le parent de force. Il appelle une fonction que le parent lui a passée en prop — un callback. C'est le parent qui décide quoi faire de l'information, et qui éventuellement met à jour ses données… ce qui relance une descente de props.
Vois ça comme une entreprise bien organisée. Les consignes descendent du patron vers les employés (les props). Les rapports remontent des employés vers le patron (les callbacks). Un employé ne va pas réécrire lui-même la stratégie du patron : il fait remonter l'info, et le patron décide. Résultat : une seule personne « possède » chaque donnée et décide quand elle change. Pas de chaos.
Pourquoi cette contrainte rend React prévisible ? Parce que pour chaque donnée affichée, il existe un seul endroit qui en est responsable, un seul propriétaire. Quand quelque chose s'affiche mal, tu n'as pas dix suspects : tu remontes le flux jusqu'au propriétaire de la donnée et tu regardes pourquoi elle a cette valeur. Compare avec un système où n'importe quel bout de code peut modifier n'importe quel élément de n'importe où : là, un bug devient une enquête sans fin. Le flux à sens unique échange un peu de liberté contre énormément de prévisibilité — un excellent marché.
// Le PARENT possède la donnée et la fait DESCENDRE en prop,
// et passe aussi un callback pour que l'enfant fasse REMONTER l'événement.
<SetRow
reps={12} // donnée qui descend (prop)
onComplete={() => marquerFait()} // événement qui remonte (callback)
/>
reps descend du parent vers SetRow. Quand l'utilisateur agit,
SetRow appelle onComplete : l'événement remonte, et c'est le parent qui
décide quoi en faire. Sens unique, toujours.
7. Les props en profondeur : en lecture seule, et composables
Les props (raccourci de « properties », propriétés) sont les données qu'un composant reçoit de son parent. C'est son entrée, ses réglages. Et il y a une règle d'or, non négociable, qui découle directement du flux unidirectionnel : vu de l'enfant, les props sont en lecture seule. Un composant peut lire ses props autant qu'il veut, mais il ne doit jamais les modifier. Elles ne lui appartiennent pas ; elles appartiennent au parent qui les lui a prêtées.
Pense à une prop comme à un document qu'on te confie en lecture. Tu peux le consulter,
t'en servir pour décider quoi afficher, mais tu n'as pas le droit de raturer dessus. Si tu griffonnes
sur le document du parent, plus personne ne sait quelle est la « vraie » valeur — et tu casses la belle
prévisibilité qu'on vient de gagner. Si un composant a besoin de faire évoluer une donnée dans le
temps, ce n'est pas une prop qu'il lui faut, c'est un état à lui (le useState du
module « useState & useEffect »).
Les enfants : la prop children
Il existe une prop spéciale, children (« enfants »), qui contient tout ce que tu places
entre les balises ouvrante et fermante d'un composant. C'est ce qui permet d'écrire des
composants « contenants », comme une carte ou un bouton, dans lesquels on glisse n'importe quoi.
// Un composant "Carte" qui ne sait pas ce qu'il contient :
function Card({ children }) {
return <View className="rounded-xl bg-card p-4">{children}</View>;
}
// On l'utilise en glissant du contenu À L'INTÉRIEUR des balises :
<Card>
<Text variant="h2">Mon entraînement</Text>
<Text>3 séries de 12</Text>
</Card>
Tout ce qui est entre <Card> et </Card> arrive dans la prop
children. La carte décide juste de l'emballage (le cadre, les marges, le fond) sans rien
savoir de son contenu.
Composer des composants
C'est ça, la composition : assembler des petits composants pour en former de plus
grands, exactement comme on emboîte des briques Lego. Un écran d'entraînement n'est pas un bloc
monolithique : c'est une Card qui contient des Text et des SetRow,
chacun étant lui-même un petit composant. Cette philosophie « petites briques réutilisables qu'on
emboîte » est le cœur de l'architecture de Halterofit, et on l'explore en détail dans le module sur les
composants. Pour l'instant, retiens l'idée : grâce à children et aux props, tu fabriques
des composants génériques (une carte, un bouton, un champ) que tu réutilises partout en
changeant juste ce qu'il y a dedans.
Le composant Text qu'on a lu plus haut récupère justement ...props et les
transmet plus bas ({...props}). C'est de la composition : Text ajoute son
style, puis « laisse passer » le reste des props (dont children, le texte affiché) vers
le composant natif en dessous. Il enrichit sans s'approprier — un bon citoyen du flux à sens unique.
8. Le re-render : ce que ça veut dire, et ce que ça ne veut pas dire
« Re-render » veut simplement dire : React rappelle ta fonction-composant pour obtenir une description à jour de l'écran. Souviens-toi de l'équation UI = fonction(état) : si une entrée change, il faut recalculer la sortie. Re-render, c'est exactement ce recalcul. Ça se produit dans exactement trois cas :
- Ses props changent — le parent lui passe de nouvelles données qui descendent.
- Son état interne change — via
useState(module « useState & useEffect »). - Son parent re-render — par défaut, quand un parent est rappelé, ses enfants le sont aussi.
« Re-render » ne veut pas dire « tout effacer et tout redessiner à l'écran ». C'est
l'erreur de modèle mental la plus fréquente, et elle fait peur pour rien. Reprends les deux phases :
un re-render, c'est surtout la phase de render (recalculer l'arbre en mémoire, ce qui est
bon marché). Ensuite seulement vient le commit, qui, grâce au diff, ne modifie à
l'écran réel que les rares parties qui ont vraiment changé. Donc : re-render ≠ tout
redessiner. Re-render = recalculer la description, puis appliquer chirurgicalement les
différences. C'est rapide — mais pas totalement gratuit quand ça se répète beaucoup, d'où les
optimisations du module sur l'optimisation des hooks (memo, useMemo).
Une fois que tu vois React comme « une fonction rappelée à chaque changement de données », tous les hooks deviennent logiques :
useState(module « useState & useEffect ») : « garde-moi cette valeur d'un appel à l'autre, et rappelle ma fonction quand elle change ».useMemo/memo(module sur l'optimisation des hooks) : « lors du prochain rappel, ne refais pas ce calcul si rien d'utile n'a changé ».
Ces outils n'ont de sens que parce que ta fonction est rappelée encore et encore. Le re-render est le battement de cœur de React.
9. Un mot sur les listes : pourquoi React réclame des key
Tu vas très vite afficher des listes : la liste des exercices, des séries, des entraînements. En React,
on transforme un tableau de données en un tableau d'éléments JSX. Et là, React demande une chose qui
surprend au début : chaque élément de la liste doit porter une prop spéciale, key, avec
une valeur unique et stable (souvent l'identifiant de la donnée).
// Chaque ligne reçoit une `key` unique et stable (ici l'id de la série).
{series.map((s) => (
<SetRow key={s.id} reps={s.reps} />
))}
La key n'est pas pour toi ni pour l'affichage : c'est un repère que React utilise en
interne pour suivre chaque élément.
Pourquoi cette exigence ? Reviens au diff. Quand la liste change — une série ajoutée,
supprimée, réordonnée — React compare l'ancienne liste et la nouvelle. Sans repère, il ne peut pas
savoir si la 3ᵉ ligne est « la même qu'avant qui a un peu changé » ou « une ligne complètement
nouvelle ». La key est l'étiquette qui dit à React « cet élément-ci est le même qu'avant,
suis-le ». Avec de bonnes keys, React déplace et conserve les éléments existants au lieu de tout
détruire et reconstruire — c'est plus rapide, et ça évite des bugs subtils (un texte saisi qui saute
d'une ligne à l'autre, par exemple). On creusera ça dans le module sur les composants ; pour l'instant,
retiens juste : les key aident React à suivre l'identité des éléments d'une liste
dans le temps.
10. Récapitulons le voyage d'un clic
Mettons toutes les pièces ensemble avec un exemple concret. L'utilisateur appuie sur « série terminée » dans Halterofit. Voici, dans l'ordre, le voyage complet à travers le modèle mental :
- L'événement remonte : le bouton enfant appelle le callback que le parent lui avait passé en prop (flux à sens unique, événements vers le haut).
- Le parent met à jour une donnée (son état) — il ne touche jamais l'écran à la main (pensée déclarative).
- Cette donnée qui change déclenche un re-render : React rappelle les fonctions concernées.
- Phase render : tes composants retournent un nouveau JSX, React calcule le nouvel arbre en mémoire (le Virtual DOM).
- React fait le diff entre l'ancien arbre et le nouveau.
- Phase commit : React applique uniquement les différences à l'écran réel. La série passe à « terminée ».
Remarque ce que tu n'as pas eu à faire : trouver le bouton, changer sa couleur, recompter, réécrire un texte, cacher un message. Tu as juste changé une donnée et décrit l'écran voulu. React a fait tout le sale boulot impératif à ta place. C'est ça, vivre dans le monde déclaratif.
Observe cet usage du composant Text tiré de l'écran d'inscription :
{error !== '' && <Text className="text-destructive">{error}</Text>}
Questions : (1) Que se passe-t-il visuellement quand error vaut une
chaîne vide '' ? (2) Le composant Text est-il « au courant » d'où vient la
valeur error ? (3) En quoi cet exemple illustre-t-il « UI = fonction(état) » ?
Voir le corrigé
(1) error !== '' && <Text>...</Text> est une astuce JS
classique : si la condition de gauche est fausse (error est vide), l'expression vaut
false et React n'affiche rien. Si error contient un message, le
<Text> est décrit, donc affiché. C'est de l'affichage conditionnel — et remarque
qu'on ne « cache »/« montre » rien à la main : on décrit deux résultats possibles selon la donnée.
(2) Non, et c'est l'essentiel : Text ne connaît que la prop
qu'on lui passe ({error}). Il ignore totalement que cette valeur vient d'un
useState dans l'écran parent. Un composant ne voit que ses props (en lecture seule),
jamais l'extérieur — c'est ce qui le rend réutilisable partout.
(3) L'écran (afficher ou non le message rouge) est entièrement le résultat
de la donnée error à l'instant T. Change error → l'interface suit
automatiquement. C'est UI = fonction(état) en une ligne : tu agis sur la donnée, jamais sur l'écran.
1. Quelle est la différence entre déclaratif et impératif, en une phrase ?
Impératif = tu donnes la suite d'étapes pour modifier l'écran à la main ; déclaratif (React) = tu décris le résultat voulu et React calcule les étapes pour toi.
2. En une phrase : qu'est-ce qu'un composant React, et que signifie « UI = fonction(état) » ?
Un composant est une fonction qui reçoit des données et retourne une description de l'écran (du JSX). « UI = fonction(état) » dit que l'interface est le résultat de tes données à un instant T : change les données, l'interface suit.
3. Cite les trois causes d'un re-render.
(1) ses props changent, (2) son état interne change (useState), (3) son parent re-render.
4. Vrai ou faux : un re-render efface tout l'écran et le redessine.
Faux. Phase render : React rappelle la fonction et recalcule l'arbre en mémoire (le Virtual DOM). Phase commit : grâce au diff, il ne modifie à l'écran que les différences. Re-render ≠ tout redessiner.
5. Dans quel sens circulent les données et les événements en React, et pourquoi c'est utile ?
Les données descendent (props, du parent vers l'enfant), les événements remontent (callbacks, de l'enfant vers le parent). Ce flux à sens unique rend l'app prévisible : chaque donnée a un seul propriétaire, donc un seul endroit à inspecter quand ça bugue.
6. À quoi sert la prop key dans une liste ?
Elle donne à React une étiquette unique et stable pour suivre l'identité de chaque élément d'un re-render à l'autre, afin de réutiliser/déplacer les éléments existants au lieu de tout reconstruire. Elle sert au diff, pas à l'affichage.
React est déclaratif : tu décris l'écran voulu, il s'occupe du « comment ». Un composant est une fonction (données → JSX), et UI = fonction(état) : l'écran n'est que le reflet de tes données. Le JSX est du sucre pour des appels de fonction qui produisent un arbre d'objets en mémoire, pas l'écran réel. React travaille en deux phases : render (calculer l'arbre, le Virtual DOM) puis commit (appliquer le diff à l'écran). Un re-render (causes : props, état, parent) recalcule la description ; re-render ≠ tout redessiner. Les données descendent (props, en lecture seule), les événements remontent (callbacks). Agis toujours sur les données, jamais sur l'écran. Tout le reste du guide découle de là.
Deux réflexes impératifs à désapprendre absolument. (1) Vouloir modifier l'écran « à
la main » — chercher un élément pour changer son texte ou sa couleur directement. En React, on ne
touche jamais l'écran : on change une donnée et on laisse le re-render faire. (2)
Vouloir muter les props (les modifier depuis l'enfant). Les props sont en lecture seule, elles
appartiennent au parent. Les raturer brise le flux à sens unique et rend les bugs impossibles à
traquer. Si une valeur doit évoluer dans un composant, elle doit devenir son état
(useState), pas une prop modifiée en douce.
Ce modèle « UI = fonction(état) », déclaratif et à flux unidirectionnel, est exactement le même sur React web et React Native (module « React Native : les briques natives »), et il a inspiré toute une génération d'outils : SwiftUI (Apple), Jetpack Compose (Android), Flutter (Google) et Vue reposent tous sur la même idée — tu décris l'interface en fonction de l'état, le framework s'occupe de la mettre à jour. Comprendre ce modèle une seule fois, en profondeur, te sert sur toutes ces technologies. C'est sans doute l'investissement le plus rentable de ta carrière de développeur d'interfaces.