đ©âđ« React Basics 04 - PokĂ©dex - Passer des props
Objectifs
- Passer des données d'un composant à un autre grùce aux props
Pré-requis
- 1
Valider les quĂȘtes suivantes
QuĂȘtes liĂ©es
Avant de commencer cette quĂȘte, modifie le fichier tsconfig.app.json de ton projet pokedex. Tu dois supprimer les lignes qui commencent par -, et ajouter les lignes qui commencent par + :
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
- "noFallthroughCasesInSwitch": true
+ "noFallthroughCasesInSwitch": true,
+ "noImplicitAny": false
},
"include": ["src"]
}
Les notions abordĂ©es dans cette quĂȘte vont dĂ©clencher des nouveaux messages de Typescript. Pour faire les choses une Ă©tape Ă la fois, nous les dĂ©sactivons pour l'instant et nous les traiterons dans la quĂȘte suivante.
Introduction
Dans les quĂȘtes prĂ©cĂ©dentes, nous avons vu comment crĂ©er et afficher des composants, comment afficher des donnĂ©es dans des composants, ainsi que comment utiliser des expressions dans le JSX.
Dans cette quĂȘte, tu vas dĂ©couvrir comment passer des valeurs d'un composant Ă un autre.

Sommaire
Une histoire d'arborescence
Si tu te souviens bien, dans les quĂȘtes prĂ©cĂ©dentes, nous avons vu la hiĂ©rarchie des composants dans React. Les props dans React permettent de faire passer des informations d'un composant Ă un autre. Mais attention : les props peuvent ĂȘtre transmises uniquement d'un composant parent vers un composant enfant.
Regarde ce schéma :

Tu peux voir que App peut transmettre des props Ă chacun de ses composants Card. Chaque composant Card peut lui-mĂȘme transmettre des props Ă son composant Button.
Comment procéder ?
Garde en tĂȘte que les composants React sont des fonctions. Tu peux imaginer le code suivant en JavaScript "vanilla" :
!--- App.js
import SayHello from "./SayHello";
function App() {
document.body.innerText = SayHello("Wilder");
}
export default App;
!--- SayHello.js
function SayHello(name) {
return `Hello ${name}!`;
}
export default SayHello;
!--- index.js
import App from "./App";
App();
Dans App.js, nous avons créé une fonction App et importé une fonction SayHello depuis un autre fichier (SayHello.js). La fonction SayHello attend en paramÚtre une chaine de caractÚre que nous lui passons lors de l'appel dans App :
SayHello("Wilder")
En React, la mĂȘme chose donnerait :
!--- App.js
import SayHello from "./SayHello";
function App() {
return SayHello("Wilder");
}
export default App;
!--- SayHello.js
function SayHello(name) {
return `Hello ${name}!`;
}
export default SayHello;
Une grosse différence : c'est React qui gÚre la manipulation du DOM à notre place. Cette partie du code dans le premier exemple a disparu :
document.body.innerText =
Dans React, tu dois passer les props au travers d'un objet et non pas directement la valeur comme dans SayHello("Wilder"). Si par le plus grand des hasards tu appelles cet objet props dans le composant SayHello, cela donne :
!--- App.js
import SayHello from "./SayHello";
function App() {
return SayHello({name: "Wilder"});
}
export default App;
!--- SayHello.js
function SayHello(props) {
return `Hello ${props.name}!`;
}
export default SayHello;
Dans React, le nom props est une convention pour le premier paramÚtre d'une fonction composant. Ici, c'est le paramÚtre qui représente l'objet avec toutes les valeurs envoyées du composant parent App au composant enfant SayHello.
Dernier point : dans React, tu manipules tes composants avec la syntaxe JSX. PlutĂŽt que la syntaxe JS SayHello({name: "Wilder"}), tu peux appeler tes composants avec la syntaxe JSX et passer tes props comme tu utiliserais des attributs en HTML :
!--- App.js
import SayHello from "./SayHello";
function App() {
return <SayHello name="Wilder" />;
}
export default App;
!--- SayHello.js
function SayHello(props) {
return `Hello ${props.name}!`;
}
export default SayHello;
Dans notre composant App, nous avons appelé notre composant SayHello en lui passant en props un couple clé/valeur : la clé est name et la valeur est "Wilder".
En fait, props est un objet qui contient toutes les clés/valeurs passées au composant. Tu peux le voir dans cet exemple :
!--- App.js
import SayHello from "./SayHello";
function App() {
return <SayHello name="Alice" age={25} />;
}
export default App;
!--- SayHello.js
function SayHello(props) {
console.log(props);
return `Hello my name is ${props.name}, I'm ${props.age}!`;
}
export default SayHello;
Tu peux voir que la syntaxe est diffĂ©rente pour name et pour age. Les chaĂźnes de caractĂšres peuvent ĂȘtre passĂ©es dans les props avec des "" comme les attributs HTML. C'est le cas pour name="Alice".
Pour toutes les autres valeurs (nombre, objet, variable...), tu dois utiliser des {} pour entourer ta valeur JavaScript. C'est le cas pour age={25}.
Quelles valeurs je peux faire passer en props ?
Dans react, tu peux passer n'importe quel type de valeur en props Ă tes composants. Des types primitifs (string, number, boolean...) et non primitifs (function, object) :
!--- App.js
import Cart from "./Cart"
function App() {
const product = {
name: "apples",
price: 1.5,
quantity: 2
}
const calculate = (product) => product.price * product.quantity
return <Cart product={product} calculate={calculate} />;
}
export default App;
!--- Cart.js
function Cart(props) {
console.log(props);
return `You bought ${props.product.quantity} ${props.product.name} for ${props.calculate(props.product)}âŹ`;
}
export default Cart;
Attention cependant Ă la façon dont tu passes tes props. Seules les chaĂźnes de caractĂšres statiques comme "Hello wilder !" peuvent ĂȘtre passĂ©es entre guillemets. Expressions, variables, fonctions et mĂȘme les template strings doivent ĂȘtre passĂ©es entre accolades.
Rendre les choses plus lisibles
Une derniÚre chose : tu peux déstructurer l'objet props dans le composant qui l'utilise.
Reprenons notre composant Cart qui actuellement ressemble Ă ceci :
function Cart(props) {
return `You bought ${props.product.quantity} ${props.product.name} for ${props.calculate(props.product)}âŹ`;
}
export default Cart;
Tu peux déstructurer l'objet props afin d'améliorer la lisibilité :
function Cart(props) {
const { product, calculate } = props;
return `You bought ${product.quantity} ${product.name} for ${calculate(product)}âŹ`;
}
export default Cart;
Le JSX est plus lisible de cette maniÚre. Pour aller plus loin, tu peux déstructurer tes props directement dans les paramÚtres de ta fonction composant :
function Cart({ product, calculate }) {
return `You bought ${product.quantity} ${product.name} for ${calculate(product)}âŹ`;
}
export default Cart;
C'est cette syntaxe nous utiliserons par défaut.
Récapitulatif
- Les
propssont toujours passées d'un composant parent vers un composant enfant. - Le mot-clé
propsest une convention pour l'objet en paramĂštre d'une fonction composant. - Les
propspeuvent ĂȘtre de n'importe quel type. - Les
propssont toujours en lecture seul.
Challenge
Dans ce challenge, tu vas utiliser le systÚme de props pour transmettre des données entre tes composants App et PokemonCard.
Rappel : avant de commencer ce challenge, tu dois modifier le fichier tsconfig.app.json de ton projet pokedex. Ton fichier doit contenir la rĂšgle "noImplicitAny": false :
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": false
},
"include": ["src"]
}
Les props dĂ©clenchent de nouveaux messages de Typescript. Pour faire les choses une Ă©tape Ă la fois, nous les dĂ©sactivons pour l'instant et nous les traiterons dans la quĂȘte suivante.
- 1
Crée une nouvelle branche
Ouvre ton projet existant et crée une nouvelle branche appelée
props.1. Cette branche sera utilisée pour développer les fonctionnalités liées aux props. Assure-toi de partir de la branchecomponents.2. - 2
Ajoute un paramĂštre props
Dans ton composant
PokemonCard, ajoute un paramÚtrepropsà la fonctionPokemonCard. Ensuite, utiliseconsole.log(props)à l'intérieur de la fonction pour afficher l'objetpropsdans la console de ton navigateur. à ce stade, tu devrais voir dans la console un objet vide.jsconst pokemonList = [ { name: "bulbasaur", imgSrc: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/1.png", }, { name: "mew", }, ]; function PokemonCard(props) { console.log(props); // ... } export default PokemonCard; - 3
Transmets un pokémon à PokemonCard via une prop
Copie le tableau
pokemonListdu composantPokemonCarddans le composantApp:jsximport "./App.css"; import PokemonCard from "./components/PokemonCard"; const pokemonList = [ { name: "bulbasaur", imgSrc: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/1.png", }, { name: "mew", }, ]; function App() { return ( <div> <PokemonCard /> </div> ); } export default App;Dans le composant
App, lĂ oĂč tu utilises le composantPokemonCard, ajoute une prop appelĂ©epokemonet attribue-lui un PokĂ©mon du tableaupokemonList:jsx<PokemonCard pokemon={pokemonList[0]} />Ce
pokemonva ainsi passer à ton composantPokemonCard: leconsole.logdansPokemonCarddevrait maintenant afficher un objet qui contient une propriétépokemon. - 4
Déstructure props pour en extraire l'objet pokemon
Dans le composant
PokemonCard, remplace le paramĂštrepropspar{ pokemon }. Ensuite :- Supprime le
console.log(props): ton code ne déclare plus de variableprops. - Supprime la ligne
const pokemon = pokemonList[0];: cette variablepokemonfait doublon avec lepokemonque tu reçois des props. - Supprime le tableau
pokemonList: le tableau qui compte maintenant est celui dansApp.
Le Pokémon devrait s'afficher comme avant dans ton navigateur. Mais maintenant, ton composant
PokemonCardest devenu complĂštement dynamique : il affiche les informations dupokemonquâil reçoit en prop, au lieu dâĂȘtre figĂ© sur un PokĂ©mon spĂ©cifique. Le code reste figĂ© dansApp, mais dansPokemonCard, il s'adapte en fonction des donnĂ©es passĂ©es en prop : c'est l'objectif pour cette Ă©tape du projet. - Supprime le
Assure-toi que ton composant PokemonCard utilise l'objet pokemon des props pour recevoir les données du Pokémon et que tout fonctionne correctement.
Fournis le lien vers la branche props.1 de ton dépÎt GitHub pour valider cette étape.
CritĂšres de validation
- Le composant
PokemonCardattend uneproppokemon. - Le composant
Appenvoie les données d'un pokémon au composantPokemonCardvia uneproppokemon. - Le pokémon s'affiche correctement.
Ce que tu devrais avoir dans :
import "./App.css";
import PokemonCard from "./components/PokemonCard";
const pokemonList = [
{
name: "bulbasaur",
imgSrc:
"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/1.png",
},
{
name: "mew",
},
];
function App() {
return (
<div>
<PokemonCard pokemon={pokemonList[0]} />
</div>
);
}
export default App;
function PokemonCard({ pokemon }) {
return (
<figure>
{pokemon.imgSrc != null ? (
<img src={pokemon.imgSrc} alt={pokemon.name} />
) : (
<p>???</p>
)}
<figcaption>{pokemon.name}</figcaption>
</figure>
);
}
export default PokemonCard;
Ressources partagĂ©es sur cette quĂȘte
- si quelquâun est en difficultĂ© pour la façon dont il est expliquĂ© sur ces queteshttps://fr.reactjs.org/docs/components-and-props.html
- Simple et clair au niveau des lienshttps://www.freecodecamp.org/news/how-to-use-props-in-react/
- vidéo explicative sur les props en françaishttps://www.youtube.com/watch?v=PvndxDHVaW8
- N'hésitez pas, cette vidéo m'a bien aidé pour comprendre le courshttps://www.youtube.com/watch?v=en0If_3jkRU
- explique simplement, en anglaishttps://dmitripavlutin.com/react-props/
- petite vidéo (en anglais) qui peut aider a comprendre les propshttps://www.youtube.com/watch?v=kHJSNFU7H4U