---
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é):

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`
:::