Kaherecode

Créer une app avec React - le React Comedy Club

Introduction

React est une bibliothèque Javascript qui permet de développer des interfaces utilisateurs (User Interfaces).

Ceci est la définition donner sur le site de React. C'est si simple que cela. Tout le travail du React se limite sur l'interface utilisateur de votre application.

Développer et publier en 2013 au sein de Facebook, React est aujourd'hui utiliser sur pratiquement toutes les applications de Facebook (Messenger, Instagram, …) mais aussi par de grands groupe comme Paypal, Netflix, … C'est de nos jours la bibliothèque Javascript la plus populaire et aussi la plus demandé sur le marché.

Là ou des frameworks comme Angular vont vous fournir un outil complet pour faire votre application, React quand à lui va s'occuper d'une seule chose, c'est l'interface, le V dans MVC (Model - View - Controller). React est donc une bibliothèque qui va vous permettre de développer des composants (boutons, carousel, carte, …, barre de navigation) qui vont à la suite former votre interface.

Bibliothèque

React est une bibliothèque et non un framework. Un framework est un ensemble d'outils qui vous apportent déjà les bases d'une application, tel un système de routing. React en lui seul ne permet de faire que l'interface, seulement la vue. Et autour de React, il y a d'autres bibliothèques développer par la communauté qui vont avec React vous permettre de faire des applications complètes, c'est le cas de react router et react redux par exemple.

Le React Comedy Club

Alors je vous explique c'est quoi ce titre. Nous allons ensemble développer une application qui va aller chercher des blagues sur Internet à travers une API et l'afficher. Vous allez voir c'est extraordinaire, je me suis marrer en faisant la démo et je sais que vous allez trop kiffer aussi. Voici un rendu de l'application finale

Le React Comedy Club

Installation

Pour commencer, nous allons d'abord installer React.

Pour installer React, il faut au parant avoir Node, NPM et create-react-app installer sur votre Ordinateur.

Si vous avez les trois installer, il faut vous placer dans le dossier ou vous voulez créer votre projet et entrer la commande:

$ npx create-react-app react-comedy-club

Creating a new React app in /home/orion/Documents/kaherecode/react-comedy-club.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts...

Attendez donc que l'installation se termine, vous allez avoir quelque chose dans le genre

  yarn start
    Starts the development server.

  yarn build
    Bundles the app into static files for production.

  yarn test
    Starts the test runner.

  yarn eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can't go back!

We suggest that you begin by typing:

  cd react-comedy-club
  yarn start

Happy hacking!

A la fin de l'installation, l'installateur nous donne des directives pour lancer notre application: il faut se rendre dans le dossier du projet avec cd et exécutez la commande yarn start

$ cd react-comedy-club
$ yarn start
yarn run v1.9.4
$ react-scripts start

Et l'application s'ouvre dans votre navigateur par défaut sur le port 3000

Page d'accueil par défaut de React

Nous pouvons maintenant ouvrir notre projet dans notre éditeur de code préféré (Visual studio code pour moi)

Pour ceux que ça intéresse, j'utilise le theme Night Owl. Si vous utilisez Visual Studio Code, vous pouvez installer les extensions: Bracket Pair Colorizer et ES7 React/Redux/GraphQL/React-Native snippets.

Ouvrez le fichier src/App.js, c'est là nous allons travailler.

Structure

Quand vous créez un projet React avec create-react-app, il y a deux fichiers principal, le fichier public/index.html et le fichier src/index.js.

Le fichier public/index.html ne contient pas grand chose, c'est là qu'est défini la structure de base d'une page HTML, plus important il y est défini l'id root

<body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
 </body>

C'est en effet dans cette div que notre application sera afficher.

Le fichier src/index.js va permettre de récupérer nos composants et les afficher dans la div#root de public/index.html

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

serviceWorker.unregister();

Sur la ligne 4, nous importons le fichier src/App.js et sur la ligne 7, le composant <App /> est afficher dans la div#root de public/index.html.

Voilà comment ça va se passer au fait, nous allons définir l'interface de notre application dans le fichier src/App.js, nous allons y dire comment les éléments de notre page vont être afficher, où est-ce que la barre de navigation sera afficher, les couleurs des boutons, … puis le fichier src/index.js va récupérer ces informations et les renvoyer au fichier public/index.html pour que celui-ci puisse les afficher dans la div#root.

JSX

Alors avant de commencer parlons un peu du contenu du fichier src/App.js. Ce fichier contient du JSX, c'est totalement similaire à du HTML, avec les balises et tout, mais c'est tout à fait différent. Le JSX (Javascript Syntax eXtension) est en quelque sorte le moteur de template de React, il va nous permettre de définir l'architecture de nos composants.

Nous allons retirer tout le contenu du fichier src/App.js pour seulement afficher le message Hello React!, voici le code

import React from "react";
import logo from "./logo.svg";
import "./App.css";

function App() {
  return (
    <div className="App">
      <h1>Hello React!</h1>
    </div>
  );
}

export default App;

Et la page affiche le message Hello React!

Nous pouvons aussi afficher des variables, disons que je veux dire bonjour à mon ami Adama

import React from "react";
import logo from "./logo.svg";
import "./App.css";

function App() {
  const name = "Adama";

  return (
    <div className="App">
      <h1>Hello {name}!</h1>
    </div>
  );
}

export default App;

Rendez-vous sur la documentation de React pour en savoir plus.

Composants (Components)

Les composants vous permettent de diviser l'interface utilisateur en éléments indépendants réutilisables et de considérer chaque élément de manière isolée. - React

Cette définition est beaucoup plus claire. Quand vous développez avec React, pensez à chaque élément de votre interface comme étant un composant: un bouton, la barre de navigation, la sidebar, une carte, … tout ces composants peuvent être utiliser indépendamment sur n'importe qu'elle partie de votre interface. Créons par exemple un composant Button dans le fichier src/App.js

import React from "react";
import logo from "./logo.svg";
import "./App.css";

function Button() {
  return <button>Hello</button>;
}

function App() {
  const name = "Adama";

  return (
    <div className="App">
      <h1>Hello {name}!</h1>

      <Button />
    </div>
  );
}

export default App;

Nous créons le composant Button avec

function Button() {
  return <button>Hello</button>;
}

Puis pour l'afficher, on l'appelle juste

<Button />

Et le bouton s'affiche bien dans la page.

Props

Les props en React sont les paramètres d'un composant, c'est tout. Ces paramètres peuvent changer à tout moment. Disons par exemple que nous voulons que le texte du bouton soit dynamique, que ce ne soit pas tout le temps Hello, pour cela nous allons utiliser les props

import React from "react";
import logo from "./logo.svg";
import "./App.css";

function Button(props) {
  return <button>{props.title}</button>;
}

function App() {
  const name = "Adama";

  return (
    <div className="App">
      <h1>Hello {name}!</h1>

      <Button title="Update" /> <br />
      <Button title="Delete" />
    </div>
  );
}

export default App;

Nous mentionnons juste l'attribut title et cet attribut est récupérer à travers {props.title} dans le composant.

La documentation sur les composants et props.

State

Les states d'un composant c'est comme les props, à la différence qu'un state est interne et n'est accessible que par le composant. Par exemple pour savoir combien de fois on a cliqué sur un bouton.

import React, { useState } from "react";
import logo from "./logo.svg";
import "./App.css";

function Button(props) {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(count + 1)}>
      {props.title} {count}
    </button>
  );
}

function App() {
  const name = "Adama";

  return (
    <div className="App">
      <h1>Hello {name}!</h1>
      <Button title="Update" /> <br />
      <Button title="Delete" />
    </div>
  );
}

export default App;

Et voilà nous utilisons ici les Hooks pour modifier le state de notre composant Button, je définis d'abord le state count qui va s'incrémenter à chaque fois que l'on clique sur le bouton, puis la méthode setCount() qui va au fait permettre de modifier le state, ensuite nous actualisons le state count à 0. Sur le bouton je rajoute un événement onClick qui va s'exécuter à chaque fois que l'on clique sur le bouton et qui va incrémenter le count en utilisant la méthode setCount(). Si vous allez sur la page, vous verrez que chaque bouton à son state qui lui est unique.

La documentation sur les states.

Notre programme

Bon trêve de théorie, nous allons maintenant nous attaquer à notre application. Pour vous faire une idée, voici à quoi va ressembler notre application

Nous aurons besoins de deux composants pour notre application, la carte pour afficher une blague et le composant App.

import React, { useState } from "react";
import logo from "./logo.svg";
import "./App.css";

function Joke(props) {
  return (
    <div className="joke">
      <p className="setup">{props.joke.setup}</p>
      <p className="punchline">{props.joke.punchline}</p>
    </div>
  );
}

function App() {
  const [joke, setJoke] = useState({
    setup: `What's the best thing about a Boolean?`,
    punchline: `Even if you're wrong, you're only off by a bit.`
  });

  return (
    <div className="App">
      <Joke joke={joke} />
      <button>another one</button>
    </div>
  );
}

export default App;

Nous avons notre composant Joke qui va recevoir un objet joke comme props et l'afficher puis le composant App qui lui définit un state joke. Le rendu de la page ressemble à ca

C'est vrai je sais, c'est moche mais nous avons quelque chose qui marche. Il faut maintenant aller récupérer la blague à l'adresse suivante et l'afficher. Alors moi j'ai voulu prendre que les blagues relatives à la programmation, pour avoir une blague au hasard c'est ici. Pour aller chercher la blague, nous allons utiliser l'API Fetch de Javascript dans une fonction fetchJoke() qui ressemble à ceci

function fetchJoke() {
  fetch("https://official-joke-api.appspot.com/jokes/programming/random")
    .then(resp => resp.json())
    .then(data => console.log(data));
}

J'utilise l'API Fetch de Javascript pour aller récupérer les données puis je les affiches dans la console (pour le moment).

Maintenant il faut charger la première blague dès que l'application démarre, nous allons le faire avec useEffect de React, cette fonction sera exécutée à chaque fois que le composant App sera rendu.

useEffect(() => {
  fetchJoke();
}, []);

Voilà, à chaque fois que le composant App sera afficher, nous allons appeler la fonction fetchJoke(). Le code de src/App.js

import React, { useState, useEffect } from "react";
import "./App.css";

function Joke(props) {
  return (
    <div className="joke">
      <p className="setup">{props.joke.setup}</p>
      <p className="punchline">{props.joke.punchline}</p>
    </div>
  );
}

function App() {
  const [joke, setJoke] = useState({
    setup: `What's the best thing about a Boolean?`,
    punchline: `Even if you're wrong, you're only off by a bit.`
  });

  useEffect(() => {
    fetchJoke();
  }, []);

  function fetchJoke() {
    fetch("https://official-joke-api.appspot.com/jokes/programming/random")
      .then(resp => resp.json())
      .then(data => console.log(data));
  }

  return (
    <div className="App">
      <Joke joke={joke} />
      <button>another one</button>
    </div>
  );
}

export default App;

Allons donc voir ce que nous avons le navigateur

Vous voyez bien dans ma console que la méthode fetchJoke() retourne un tableau d'une seule blague (c'est vrai que c'est bizarre, mais ce n'est pas notre API).

Ce que nous allons maintenant faire, c'est récupérer cette blague et la mettre dans notre state joke. Pour cela il suffit juste de modifier notre fonction fetchJoke()

import React, { useState, useEffect } from "react";
import "./App.css";

function Joke(props) {
  return (
    <div className="joke">
      <p className="setup">{props.joke.setup}</p>
      <p className="punchline">{props.joke.punchline}</p>
    </div>
  );
}

function App() {
  const [joke, setJoke] = useState({
    setup: ``,
    punchline: ``
  });

  useEffect(() => {
    fetchJoke();
  }, []);

  function fetchJoke() {
    fetch("https://official-joke-api.appspot.com/jokes/programming/random")
      .then(resp => resp.json())
      .then(data => setJoke(data[0]));
  }

  return (
    <div className="App">
      <Joke joke={joke} />
      <button>another one</button>
    </div>
  );
}

export default App;

Au lieu d'afficher le résultat dans la console, on utilise setJoke() pour mettre à jour le state joke. Si vous essayez, vous verrez que les blagues changent maintenant, mais il faut recharger la page pour avoir une autre blague. Le bouton ne marche pas pour l'instant. Pour remédier à cela, nous allons juste appeler la fonction fetchJoke() à chaque fois que le bouton est cliqué

import React, { useState, useEffect } from "react";
import "./App.css";

function Joke(props) {
  return (
    <div className="joke">
      <p className="setup">{props.joke.setup}</p>
      <p className="punchline">{props.joke.punchline}</p>
    </div>
  );
}

function App() {
  const [joke, setJoke] = useState({
    setup: ``,
    punchline: ``
  });

  useEffect(() => {
    fetchJoke();
  }, []);

  function fetchJoke() {
    fetch("https://official-joke-api.appspot.com/jokes/programming/random")
      .then(resp => resp.json())
      .then(data => setJoke(data[0]));
  }

  return (
    <div className="App">
      <Joke joke={joke} />
      <button onClick={() => fetchJoke()}>another one</button>
    </div>
  );
}

export default App;

Tu peux maintenant t'amuser.

Styling

Maintenant que nous avons notre application qui fonctionne, il nous faut arranger un peu son design. Avec React, vous pouvez aussi utiliser CSS, Sass, Less, … ou ce que vous avez l'habitude d'utiliser. Si vous regardez bien, il y a deux fichiers CSS dans src à savoir src/index.css et src/App.css. Le premier src/index.css est le fichier de base, c'est celui utilisé par src/index.js, le second src/App.css est le fichier de style du composant src/App.js. Nous allons ici utiliser juste le fichier src/App.css. J'ai bricolé un peu de CSS pour parvenir à ça

@import url("https://fonts.googleapis.com/css?family=Cormorant|Overpass");

body {
  background: linear-gradient(to right, #40e0d0, #1bbfaf);
  font-family: "Overpass";
  padding-top: 50px;
  position: relative;
  display: flex;
  justify-content: center;
}

.App {
  background-color: #fff;
  padding: 50px;
  border-radius: 5px;
  width: 450px;
}

.joke p.setup {
  text-indent: 3rem;
  position: relative;
}

.joke p.setup::before {
  content: open-quote;
  font-size: 5rem;
  font-weight: bold;
  position: absolute;
  left: -3rem;
  top: -1rem;
  color: #1bbfaf;
}

.joke p {
  font-size: 1.8rem;
}

.joke p.punchline {
  text-transform: uppercase;
  font-weight: bold;
}

.btn {
  text-transform: uppercase;
  background: linear-gradient(to right, #40e0d0, #1bbfaf);
  color: #fff;
  border: none;
  border-radius: 0;
  padding: 1rem 2rem;
  cursor: pointer;
  font-weight: bold;
  font-size: 1rem;
  text-decoration: none;
}

.btn:focus,
.btn:active {
  border: none;
  outline: none;
}

.btn:active {
  transform: scale(0.98);
}

.btn.tweet {
  float: right;
}

Vous mettez donc ce contenu dans le fichier src/App.css et vous devriez avoir cela

Et voilà, notre application est maintenant fonctionnelle, et jolie aussi, sinon ben retravailler le design comme vous le souhaitez.

J'espère que vous vous êtes aussi amusé que moi à travailler sur ce projet, vous pouvez revoir la démo sur Netlify ou le code source sur Github. A bientôt pour une nouvelle aventure et n'oubliez pas: Le moyen orienté objet de devenir riche… c'est L'HERITAGE.


Merci à

Mamadou Aliou Diallo

Mamadou Aliou Diallo

@alioukahere

Développeur web fullstack avec une passion pour l’entrepreneuriat et les nouvelles technologies. Fondateur de Kaherecode.

Continue de lire