--- tags: ironhack, lecture --- React | JSX and Elements -- lecture === Voir le cours : http://learn.ironhack.com/#/learning_unit/6806 🛸 JSX ? --- dans `App.render()`: ```jsx ... return ( <div className="App"> <h1>Bonjour!</h1> </div> ); ... ``` 🤨 du **HTML dans du JS** ?? --- Si on essaye dans une console JS: ```js var toto = <h1 className="titre">hey</h1> ``` On obtient : ``` ❌ Uncaught SyntaxError: Unexpected token < ``` :::warning ☝️ Il ne s'agit donc ni d'une `String` ni de HTML. ::: --- Si l'on essaye dans la [REPL Babel](https://babeljs.io/repl) (avec le preset `React` coché): ![](https://i.imgur.com/pw6GW2R.png) On voit qu'il s'agit en fait d'une **syntaxe spéciale** convertit par Babel en un appel à la fonction `React.createElement` ```js const toto = React.createElement("h1", {className: "titre"}, "hey"); ``` ce qui une fois exécuté en JS retourne : ```js { type: 'h1', props: { className: 'titre' children: 'hey' } } ``` **Un élément React !!!** :::success 🍭 On voit alors clairement que le JSX est simplement du sucre: une syntaxe spéciale qui compile en du Javascript. ::: --- NB : On pourrait tout aussi bien écrire nous-même chaque balise HTML en un appel `React.createElement()` mais cela serait alors très fastidieux et peu pratique : ```jsx <div className="App"> <h1>Bonjour!</h1> </div> ``` donnerait ```js React.createElement( "div", {className: "App"}, React.createElement("h1", null, "Bonjour!") ); ``` :::warning ☝️ `class` étant un mot-clef réservé du language, on comprend pourquoi en JSX on devra banir l'utilisation de l'attribut HTML `class="` mais **`className="`** à la place. ::: :::success 🐣 On peut "voir" JSX comme un nouveau type de variable Javascript pour écrire facilement du HTML. ::: les expressions JSX --- En JSX, tout ce qui se trouve entre des accolades peut être n'importe quelle expression Javascript, comme par ex : Testons cela sur : https://codepen.io/abernier/pen/VgOyYE?editors=0010 - une **opération** : ```jsx <p>Un et deux font {1+2}</p> ``` - une **variable** : ```jsx <p>π vaut environ {Math.PI}</p> ``` - n'importe quelle **fonction** : ```jsx <p>Apparemment tu vas : {prompt("Comment vas-tu ?")}.</p> ``` - un **commentaire** : ```jsx <p>Je ne dirai rien... {/* mais je n'en pense pas moins */}</p> ``` :::info 💪 On dispose ainsi de toute la puissance de javascript pour écrire nos templates. ::: ### Exercice guidé Dans notre application du cours précédent, créons un objet `user` dans `index.js`: ```js const user = { firstname: "John", lastname: "Doe", address: { num: 9, street: "passage Imbert" }, emails: [ "jdoe@gmail.com", "jdoe@ironhack.com" ], avatarUrl: "https://i.imgur.com/fGcHrJy.jpg" }; ``` Et imprimons dans notre `App.render()` : ```jsx <p>Bonjour je suis {user.firstname} !</p> <p>J'habite {user.address.street}.</p> <p>Mon mail principal est : {user.emails[0]}.</p> ``` --- Créons maintenant une fonction `formatName` : ```jsx const formatName = (firstname, lastname) => { return `${firstname} ${lastname}`; }; ``` et remplaçons par l'appel à cette fonction : ```jsx <p>Bonjour je suis {formatName(user.firstname, user.lastname)} !</p> ``` --- Rajoutons notre avatar : ```jsx <p>Et me voici : <img src={user.avatarUrl} alt="ma tête" /> !</p> ``` :::info 👉 Notez que la valeur de l'attribut `src="` n'est pas entre guillemets, mais directement `src={`. Par contre on a bien classiquement `alt="ma tête"`. ::: :::warning ☝️ Notez également la balise explicitement **auto-fermante OBLIGATOIRE** en JSX, ie: `/>` ::: --- Définissons maintenant une fontion `displayAvatar` : ```jsx function displayAvatar(url) { if (url) { return <img src={url} />; } else { return <img src="https://twirpz.files.wordpress.com/2015/06/twitter-avi-gender-balanced-figure.png?w=1280" />; } } ``` Et utilisons la dans notre `render()` : ```jsx <p>Et me voici : {displayAvatar(user.avatarUrl)} !</p> ``` --- Une fois de plus, pour écrire du JSX sur plusieurs lignes, on oublie pas les parenthèses : ```jsx const moi = ( <div> <p>Bonjour je suis {user.firstname} !</p> <p>J'habite {user.address.street}.</p> <p>Mon mail principal est : {user.emails[0]}.</p> <p>Et me voici : {displayAvatar(user.avatarUrl)} !</p> </div> ); ``` :::warning ☝️ De plus, du JSX retournant un élément React et un seul, on entoure ici nos différentes lignes HTML d'**une unique `div` englobante**. Autrement on aurait alors une erreur : ``` ❌ Adjacent JSX elements must be wrapped in an enclosing tag ``` ::: ```jsx render() { return ( <div className="App"> {moi} </div> ); } ``` --- Pour les évenements : ```jsx <a onClick={() => alert("salut");}>clickme</a> ``` :::warning ☝️ En JSX, on utilisera la notation camelcase `onClick`, pas `onclick` :::