1.0.3 • Published 2 years ago

sqli-react-boilerplate v1.0.3

Weekly downloads
-
License
MIT
Repository
gitlab
Last release
2 years ago

Boilerplate React - SQLI

Démarrage

Commençons les étapes pour avoir son environnement ReactJS prêt à l'emploi.

Tout d'abord, nous pouvons commencez par un café ensemble ;)

Après avoir récupérer vos Ordinateurs au CRCI au 7ème étage Et vous avez fait la demande à votre manager pour avoir accès au GitLab Paris

Nous pouvons initialiser le projet

Installation du Boilerplate - SQLI

  • Créer un dossier Workspace dans votre dossier Documents

  • Dans la console entrer la commande suivante `npx sqli-react-boilerplate

  • Puis cd <nom du projet>

Vous voilà enfin prêt à commencer l'aventure.

Liens utiles

Les deux choses utiles à comprendre pour l'intégration sont:

  1. La syntaxe JSX
  2. Le fonctionnement de React

Voici quelques liens utiles:

##Testons-nous avec quelques exercices

Dojo Numéro 1

  • Création d'un composant compteur
  • en utilisant un hooks useState()

    Dojo Numéro 2

  • Comment créer une carte à onglets personnalisée avec React, Styled-Component

  • Si vous voulez en savoir plus sur Styled-Component, vous pouvez consulter ce lien.

    Dojo Numéro 3

  • Comment utiliser Redux dans reactJS pour crée une Todo List

  • Pour plus d'infos sur redux

    Dojo Numéro 4

  • Installation de React sur un projet AEM

  • Création d'un composant contribuable
  • vous trouverez le code source ici en me demandant l'accès à mon gitlab perso

Dojo Numéro 5

  • Créons un tic-tac-toe étapes par étapes
  • Tout d'abord crée un nouveau projet React à l'aide de notre BoilerPlate SQLI (vous connaissez maintenant la commande)

    Construison notre application :

  • Tout d'abord dans le fichier src/App.js, créez une fonction appelée calculateWinner pour obtenir le gagnant d'un tableau.

  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ]
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i]
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a]
    }
  }
  return null

Nous stockons un motif de lignes en cas de gagnant dans un tableau de lignes et si nous voyons l'un de ces motifs à tout moment du jeu, nous déclarerons le gagnant.

  • Pour calculer le prochain tour, créez une fonction appelée calculateNextValue
  return squares.filter(Boolean).length % 2 === 0 ? 'X' : 'O'
}
  • Pour voir l'état actuel du jeu nous pouvons crée la fonction suivante :
function calculateStatus(winner, squares, nextValue) {
  return winner
    ? `Winner: ${winner}`
    : squares.every(Boolean)
    ? `Scratch: Cat's game`
    : `Next player: ${nextValue}`
}
  • Vous pouvez modifier le CSS pour rendre le jeu plus attractif
  • Passons à la création du plateau de jeu
function Board() {
  const [squares, setSquares] = React.useState(Array(9).fill(null))

  const nextValue = calculateNextValue(squares)
  const winner = calculateWinner(squares)
  const status = calculateStatus(winner, squares, nextValue)

  function selectSquare(square) {
    if (winner || squares[square]) {
      return
    }
    const squaresCopy = [...squares]
    squaresCopy[square] = nextValue
    setSquares(squaresCopy)
  }

  function restart() {
    setSquares(Array(9).fill(null))
  }

  function renderSquare(i) {
    return (
      <button className="square" onClick={() => selectSquare(i)}>
        {squares[i]}
      </button>
    )
  }

  return (
    <div>
      <div className="status">{status}</div>
      <div className="board-row">
        {renderSquare(0)}
        {renderSquare(1)}
        {renderSquare(2)}
      </div>
      <div className="board-row">
        {renderSquare(3)}
        {renderSquare(4)}
        {renderSquare(5)}
      </div>
      <div className="board-row">
        {renderSquare(6)}
        {renderSquare(7)}
        {renderSquare(8)}
      </div>
      <button className="restart" onClick={restart}>
        restart
      </button>
    </div>
  )
}
  • Créez maintenant une fonction Game() et placez à l'intérieur notre composant Board() puis rajouter le compoant Game() dans le composant parent App()
  • À la fin, notre App.jsdevrait ressembler à ceci.
import React from 'react';
import "./App.css";

function Board() {
  const [squares, setSquares] = React.useState(Array(9).fill(null))

  const nextValue = calculateNextValue(squares)
  const winner = calculateWinner(squares)
  const status = calculateStatus(winner, squares, nextValue)

  function selectSquare(square) {
    if (winner || squares[square]) {
      return
    }
    const squaresCopy = [...squares]
    squaresCopy[square] = nextValue
    setSquares(squaresCopy)
  }

  function restart() {
    setSquares(Array(9).fill(null))
  }

  function renderSquare(i) {
    return (
      <button className="square" onClick={() => selectSquare(i)}>
        {squares[i]}
      </button>
    )
  }

  return (
    <div>
      <div className="status">{status}</div>
      <div className="board-row">
        {renderSquare(0)}
        {renderSquare(1)}
        {renderSquare(2)}
      </div>
      <div className="board-row">
        {renderSquare(3)}
        {renderSquare(4)}
        {renderSquare(5)}
      </div>
      <div className="board-row">
        {renderSquare(6)}
        {renderSquare(7)}
        {renderSquare(8)}
      </div>
      <button className="restart" onClick={restart}>
        restart
      </button>
    </div>
  )
}

function Game() {
  return (
    <div className="game">
      <div className="game-board">
        <Board />
      </div>
    </div>
  )
}

function calculateStatus(winner, squares, nextValue) {
  return winner
    ? `Winner: ${winner}`
    : squares.every(Boolean)
    ? `Scratch: Cat's game`
    : `Next player: ${nextValue}`
}

function calculateNextValue(squares) {
  return squares.filter(Boolean).length % 2 === 0 ? 'X' : 'O'
}

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ]
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i]
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a]
    }
  }
  return null
}

function App() {
  return <Game />
}

export default App

Installations des dépendances les plus utilisés

####redux :

  • Installations npm install redux
  • Package complémentaires
    npm install react-redux npm install --save-dev redux-devtools####json server :
  • Installation npm install json-server
  • Création d'un base de donnée db.json à la racine du projet
  • Dans package.json rajoutez un script pour json-server "server": "json-server --watch -p 3001 db.json"
  • démarrer le script : npm run server

    ####Apollo :

  • Installation npm install apollo

  • Création d'un service apolloClient.js
    import {
     ApolloClient,
     InMemoryCache,
     HttpLink
    } from "@apollo/client";

const cache = new InMemoryCache(); const link = new HttpLink({ uri: ${REACT_APP_API_URL}/graphql }); const client = new ApolloClient({ cache, link,

});

export default client;

   * Créer un autre service Query 
   ```js
import React from 'react';
import { useQuery } from '@apollo/client';

const Query = ({ children, query, variables, loader }) => {
    const { data, loading, error } = useQuery(query, {
        variables
    });
    if (loading) return loader;
    if (error) {
        return (
            <p>
                Error:
                {JSON.stringify(error)}
            </p>
        );
    }
    return children({ data });
};
export default Query;
  • Maintenant il suffit d'utiliser vos services pour recuperer vos informations de votre API en utilisant le composant Query

Exemples

Voici quelques exemples et recommandation utiles

Composants purs

Sachant que le site n'a pas besoin d'interactivité JS, l'intégration n'a besoin que de composants react "purs" et n'a pas besoin de toutes les fioritures des classes de composant etc. Cela est bien plus simple.

Un composant pur, pour react, n'est ni plus ni moins qu'une fonction prenant des props (les données au format du modèle) comme arguments et renvoyant du html (via la syntaxe JSX).

Les composants, par convention, ont un nom écrit en TitleCase (majuscule sur tous les mots, y compris le premier).

// Ceci est un composant pur renvoyant simplement une div wrappant un titre
// dont le texte est donné en props du composant
function MonComposantPur(props) {
  return (
    <div>
      <h1>{props.title}</h1>
    </div>
  );
}
// Ce composant s'utilise alors de la manière suivante:
<MonComposantPur title="Super Titre" />
// Cela rendra:
<div>
  <h1>Super Titre</h1>
</div>

Conditions

Les conditions se font en JavaScript. Plusieurs solutions existent pour intégrer des conditions dans le JSX comme utiliser les opérateurs booléens et les ternaires.

// Si l'on veut afficher quelque chose que si une condition est remplie
<div>
  {condition && <h1>Titre</h1>}
</div>
// Si l'on veut afficher soit quelque chose soit autre chose en fonction
// d'une condition
<div>
  {condition ?
    (<h1>Titre Un</h1>) :
    (<h2>Titre Deux</h2>)}
</div>
// Si jamais on veut faire des choses plus complexes et utiliser de vraies conditions
let body = null;
if (lang === 'en') {
  body = <span>Hello</span>
}
else {
  body = <span>Bonjour</span>
}
<div>{body}</div>

Exemple de rendu conditionnel ou l'on affiche ou pas une image dans une nav en fonction des props.

function Nav(props) {
  let img = null;
  if (props.image) {
    img = (
      <div>
        <img src={props.image} />
      </div>
    );
  }
  return (
    <nav>
      <h1>{props.title}</h1>
      {img}
    </nav>
  );
}
// On l'appelera comme ceci, sans image
<Nav title="Super title" />
// Et comme ceci avec une image
<Nav image="project.png" title="Super title" />

Les boucles

Le JSX est du JavaScript "augmenté". Pour faire des boucles il suffit donc d'utiliser les outils du JavaScript. Le plus utile est en général d'utiliser la méthode map des arrays.

function MonComposant(props) {
  // People est ici une liste de {firstName, lastName}
  const people = props.people;
  // Utilisons .map pour rendre une <ul>
  return (
    <ul>
      {people.map((person, i) => {
        return (
          <li key={i}>
            {person.firstName} {person.lastName}
          </li>
        );
        // L'attribut key est utilisé par React pour optimiser les mises à jour des composants
        // Dans notre cas ce n'est pas indispensable mais React génère des warnings si il manque des key
        // Donc mieux de les ajouter mais pas grave si c'est oublié
      })}
    </ul>
  );
}

Style

Pour ajouter du style directement aux éléments, react accepte des objets de style plutôt qu'une chaîne de caractère.

// Par exemple ce style:
'text-decoration: underline; color: blue;'
// Deviens cet objet:
const style = {
  textDecoration: 'underline',
  color: 'blue'
}
// Bien noter que le kebab-case du CSS se transforme en camelCase en JSX.
// Ensuite pour utiliser cet objet de style, faire soit:
<div style={style} />
// ou directement inline (notez les doubles accolades)
<div style={{color: 'blue'}} />

Concernant les classes

Dans le HTML, l'attribut de classe s'appelle class. Cependant, en JSX, afin de mimer le comportement du JavaScript, l'attribut s'appelle className.

// Wrong
<div class="column" />
// Right
<div className="column" />

Astuce: utiliser la librairie classnames.

Il n'est pas rare de vouloir composer des classes de manière conditionnelle. Comme il peut vite être fastidieux de faire cela à la main en concaténant des chaînes de caractère, il existe la lib classnames qui simplifie ce travail.

import cls from 'classnames';
// Exemple: la div a la classe column et la classe hidden si une condition est
// fausse
const className = cls('column', isHidden && 'hidden');
<div className={className} />

Enfants

Il peut être utile de faire des composants ayant pour objectif de rendre des enfants. Par exemple, le composant Layout représente le header, le footer et tout ce qui est présent sur toutes les pages et ce composant se charge ensuite de rendre ses enfants, le composant affichant ce qui est spécifique à la page people, par exemple.

// Si l'on passe des enfants à un composant, alors il aura une prop "children"
function Layout(props) {
  // Ici on rends "props.children" à l'intérieur d'une div
  return (
    <div className="container">
      <div className="column">
        {props.children}
      </div>
    </div>
  );
}
// Dès lors, si l'on écrit ceci:
<Layout>
  <h1>Titre</h1>
</Layout>
// On va rendre au final:
<div class="container">
  <div class="column">
    <h1>Titre</h1>
  </div>
</div>

Composants jumeaux sans div parente

Pour créer un composant qui rends deux blocs qui sont jumeaux sans avoir un conteneur div créé automatiquement pour les nester, il faut utiliser une syntaxe particulière:

<>
  <nav/>
  <main>content</main>
</>