React : La Révolution des Views (?) (cÎté front)
Nous parlerons de:
- Installation des prĂ©requis : Node, Express, Pulldown âŠ
- Ecrire nos composants React
- La mĂȘme chose mais avec lâaide de RequireJS
BriĂšvement, React, quâest-ce que câest ? Câest tout simplement une librairie javascript issue de chez Facebook pour dĂ©velopper des IHM. La particularitĂ© de React, câest dâutiliser sa propre implĂ©mentation du Virtual DOM. Il a Ă©tĂ© dĂ©veloppĂ© en pensant performance, il nâadresse que la partie âViewâ et pour information lâihm de la version web dâInstagram est entiĂšrement dĂ©veloppĂ©e avec React (et quelques parties de Facebook aussi).
Codes sources de lâarticle
- la version sans requirejs : https://github.com/k33g/hello.react/tree/without-requirejs
- la version avec requirejs : https://github.com/k33g/hello.react
Jâai Ă©crit cet article en une seule passe sans mâarrĂȘter, il mĂ©rite certainement encore quelques relectures, mais je ne rĂ©siste pas Ă la tentation de le publier en lâĂ©tat.
Avertissements
Attention ça peut piquer les yeux
Alors, avant de commencer, il faut savoir que React propose une syntaxe âtrĂšs (trĂšs)particuliĂšreâ : vous allez mĂ©langer votre code HTML (en fait câest une sorte de XML appelĂ© JSX) avec votre code javascript!!! LĂ je vais encore me prendre une brassĂ©e par quelques intĂ©grateurs html, et peut-ĂȘtre mĂȘme par des puristes du javascript, mais peu importe, si Facebook le fait, ça vaut peut-ĂȘtre au minimum le coup dây jeter un coup dâĆil. Et il est probablement temps que les 2 mĂ©tiers fassent quelques pas lâun vers lâautre et rĂ©flĂ©chisse Ă la maniĂšre de faire Ă©voluer leurs mĂ©tiers respectifs.
Notre 1er composant va ressembler Ă ceci :
Ăa calme! non? ;) Prenez un peu de temps et visionnez ceci http://www.youtube.com/watch?v=x7cQ3mrcKaY
Lâutilisation de JSX nâest pas obligatoire, vous pouvez faire du pur javascript, mais JSX est beaucoup plus simple Ă utiliser et facilite les travaux dâintĂ©gration.
Attention ⊠again
Mon javascript ne sera pas compatible tout navigateur âŠ
Je vais utiliser des espĂšces de âcustom tagsâ, parce que chez Google et Mozilla ils pensent que câest lâavenir :
Et jâai encore moins de scrupule Ă le faire quand Douglas Crockford en parle aussi : http://www.crockford.com/html/.
Si ça vous choque, ne me lisez pas ou entamons une discussion (calme ;)) et imaginons notre futur avec des React, Polymer, X-Tags, âŠ
Allez, on attaque.
Pré-requis
Nous allons dans un 1er temps créer la stack de travail :
Création de la partie serveur : Node
Nous allons utiliser le framework Express : http://expressjs.com/
Dans votre répertoire projet, créez un fichier package.json
:
{
"name": "hello-react",
"description": "hello-react app",
"version": "0.0.1",
"dependencies": {
"express": "3.x",
"node-uuid" : "x.x"
}
}
Puis, tapez (nous sommes dans la console) npm install
pour installer les dépendances
Remarque: node-uuid permet de générer des identifiants uniques.
Ensuite, un peu de code applicatif, câest Ă dire les âAPIâ qui nous serviront Ă fournir de la data Ă notre front js, crĂ©ez dans votre rĂ©pertoire un fichier app.js
avec le code suivant:
Création de la partie front
# Les librairies javascript du projet
Nous allons utiliser :
Cette fois-ci nous allons faire plus simple que la derniĂšre fois avec Bower), nous allons utiliser Pulldown : https://npmjs.org/package/pulldown qui est un simple âdownloaderâ de script, extrĂȘmement pratique.
Pour installer Pulldown : sudo npm install -g pulldown
Ensuite, créez un répertoir public
, puis créez un fichier loadjs.sh
que vous rendrez exécutable (chmod a+x loadjs
) avec le contenu suivant :
# === jQuery ======================
# http://jquery.com/
# =================================
pulldown jquery -o js/vendors
# === react =========================
# http://facebook.github.io/react
# ===================================
pulldown "http://cdnjs.cloudflare.com/ajax/libs/react/0.8.0/JSXTransformer.js" -o js/vendors
pulldown "http://cdnjs.cloudflare.com/ajax/libs/react/0.8.0/react.min.js" -o js/vendors
# === Skeleton ======================
# http://www.getskeleton.com/
# ===================================
pulldown "https://raw2.github.com/dhg/Skeleton/master/stylesheets/base.css" -o stylesheets
pulldown "https://raw2.github.com/dhg/Skeleton/master/stylesheets/layout.css" -o stylesheets
pulldown "https://raw2.github.com/dhg/Skeleton/master/stylesheets/skeleton.css" -o stylesheets
Dans le répertoire public
, lancez ./loadjs.sh
# Remarques :
- la partie concernant Skeleton, nâest pas obligatoire, câest un framework css pour faire âjoliâ
- si vous ĂȘtes sous Windows, pour utiliser Pulldown, crĂ©ez un fichier
load.cmd
, copiez les commandes âpulldownâ ci-dessus et ajoutezcall
avant chaquepulldown
, par exemple :call pulldown jquery -o js/vendors
# Préparation de la page index.html
Créez dans public
le fichier index.html
avec le code suivant :
Câest parti, on fait du React
1er composant : un titre paramétrable
Remarque prĂ©liminaire: nous allons faire de la transformation âonlineâ du code React. Si vous souhaitez prĂ©-compiler votre code pour optimiser votre web application, utilisez ceci : http://facebook.github.io/react/docs/getting-started.html# offline-transform.
Dans public
créez un répertoire components
, et dans ce répertoire un fichier HelloTitle.js
:
Attention: ne pas oublier /** @jsx React.DOM */
en en-tĂȘte de fichier.
this.props.message
: le composant a une propriétémessage
,this.props
âporteâ les propriĂ©tĂ©s du composant (de la mĂȘme maniĂšreversion
est aussi une propriété du composantHelloTitle
)- Non, ce nâest pas une erreur, dans le
return
de la méthoderender
, ce nâest pas une string mais bel et bien une sorte de pseudo HTML, en fait câest plutĂŽt du XML, il faut donc bien fermer tous les tags (comme pour<hr></hr>
), dans le cas de React on parle de syntaxe JSX (JavaScript XML : http://facebook.github.io/react/docs/jsx-in-depth.html).
Maintenant, je souhaite positionner mon composant dans ma page HTML. Jâajoute un tag <hello-title></hello-title>
dans lequel viendra sâinsĂ©rer le code gĂ©nĂ©rĂ© de notre composant :
Remarque : jâaurais pu tout aussi bien faire quelque chose comme ceci : <div id="hello-title"></div>
, mais dâun point de vue lisibilitĂ© je prĂ©fĂšre ma mĂ©thode.
Il nous reste plus quâĂ Ă©crire le bout de code qui dĂ©clenche le rendu de notre composant :
Créez à la racine de public/js
un fichier main.js
:
- Ne pas oublier
/** @jsx React.DOM */
- Câest ici que lâon passe les valeurs des propriĂ©tĂ©s du composant
- Si jâavais utilisĂ©
<div id="hello-title"></div>
, il faudrait Ă©criredocument.querySelector('# hello-title')
au lieu dedocument.querySelector('hello-title')
Retournons une derniĂšre fois dans index.html
pour déclarer notre composant, juste avant le tag de fermeture </body>
:
- Notez bien
type="text/jsx"
dans les inclusion de script, cela permet au âtranspilerâ JSX dâutiliser nos scripts.
Vous pouvez maintenant démarrer votre application : node app.js
et ouvrez dans votre navigateur préféré : http://localhost:3000.
2 Ăšme composant : la liste des âbuddiesâ
Nous allons afficher la liste des âbuddiesâ fournis par notre application Express :
Dans public/components
, créez un fichier HelloBuddies.js
:
getInitialState()
est une mĂ©thode de React qui permet de dĂ©finit lâĂ©tat initial des variables âattachĂ©esâ aux composants- Pour ensuite modifier ces variables on utilisera
this.setState({le_nom_de_la_variable:valeur})
- Pour lire le contenu de ces variables :
this.state.le_nom_de_la_variable
getAllBuddies()
est une fonction utilisateur : câest elle qui va faire une requĂȘte de type REST au serveur pour obtenir la liste des buddies et modifierthis.state.data
quand elle recevra les donnéescomponentWillMount()
est une mĂ©thode React, on peut lâassimiler Ă une sorte dâinit()
ouinitialize()
qui est déclenchée à la création du composant. Il existe aussicomponentDidMount()
une fois que le composant est âancrĂ©â dans le DOM. DanscomponentWillMount()
nous demandons dâexĂ©cutergetAllBuddies()
toutes les N (this.props.pollInterval
) millisecondes. Ainsi, Ă chaque fois que les variables (dansstate
) du composant sont modifiées, la méthoderender
sera appelée.
Nous modifions notre code html de la maniĂšre suivante avec le tag <hello-buddies></hello-buddies>
:
Tout en nâoubliant pas de dĂ©clarer notre nouveau composant :
Il ne reste plus quâĂ dĂ©clarer le composant et le rendu de celui-ci dans main.js
:
Remarque: notez la dĂ©claration de la valeur de lâintervalle de pooling au sein du composant (pollInterval
)
Vous pouvez rafraĂźchir votre page :
3 Úme et dernier composant : le formulaire pour créer des buddies
Dans public/components
, créez un fichier HelloBuddyForm.js
:
- Dans le code JSX du composant, si lâon souhaite que les Ă©lĂ©ments du DOM soit accessibles Ă partir du code javascript du composant, il faut leur ajouter un attribut
ref
avec le nom du composant :<input type="text" placeholder="name" ref="name"/>
et ensuite React vous permet dâinteragir avec de la maniĂšre suivante :this.refs.name.getDOMNode()
- Donc dans notre exemple nous avons un champ texte
<input>
avec une ârĂ©fĂ©renceâname
et nous pouvons accĂ©der Ă lâensemble de ses propriĂ©tĂ©s (et les modifier) et de ses mĂ©thodes (ex:focus()
)
Une fois notre composant écrit, nous allons le déclarer dans la page html avec le tag <hello-buddy-form>
:
Et en ajoutant :
Et enfin dans main.js
:
Vous pouvez rafraĂźchir votre page :
VoilĂ . Nous avons fais un 1er tour rapide. Mais encore une ou deux petites choses âŠ
On fait encore du React, mais avec RequireJS
Cela peut vite devenir le foutoir, quand les composants vont se multiplier. Donc vous aurez certainement envie de structurer tout ça avec RequireJS. Il se trouve quâil existe un plugin pour pouvoir utiliser JSX : https://github.com/seiffert/require-jsx et ainsi de dĂ©finir les dĂ©pendances (et chargement) de nos composants de cette maniĂšre : 'jsx!components/nom_du_composant'
.
Nouvelles dépendances
Donc dans votre petit script loadjs.sh
vous pouvez ajouter 2 lignes :
pulldown require.js -o js/vendors
pulldown "https://raw2.github.com/seiffert/require-jsx/master/jsx.js" -o js/vendors
Vous pouvez à nouveau relancer votre script pour récupérer les 2 nouvelles librairies
Ensuite dans votre page index.html
, supprimer les inclusion de script et remplacez les par <script data-main="js/main" src="js/vendors/require.min.js"></script>
On refait main.js
Allez ensuite remplacer le contenu de main.js
par ceci :
Création de Application.js
Créez un répertoire application
dans public/js/
et dans ce répertoire un fichier Application.js
:
Modifions tous nos composants
Câest assez simple Ă faire, globalement nous avons juste Ă les encapsuler dans une dĂ©claration define
sans oublier la directive /** @jsx React.DOM */
:
Nous aurons donc :
# HelloTitle
# HelloBuddies
# HelloBuddyForm
⊠Thatâs all!
Amusez vous bien! Retours et discussions bienvenus!
PS: ça marche aussi trÚs bien avec Backbone : http://www.thomasboyt.com/2013/12/17/using-reactjs-as-a-backbone-view.html
Tweet