React

Philosophie

Introduction

  • Dev par Facebook en 2013
  • JSX (aujourd'hui TSX)
  • Approche composant avec une gestion du cycle de vie et des états locaux (states)

Version notables

  • 16.0 (2017) -> Fragments, changement dans le cycle de vie, Server Side Rendering
  • 16.3 (2018) -> Context API
  • 16.8 (2019) -> Hooks
  • 18 (2022) -> Concurrent management

Architecture

                        ┌───────────────────┐
                        │                   │
                        │  React Component  │
     Props  ──────────► │                   │ ──────────►   render
                        │  - State          │
                        │                   │
                        └───────────────────┘

Props

  • C'est récupéré depuis le composant qui instancie. C'est une ressource immutable :
class Cat extends React.Component {
  render() {
    return <h1>{this.props.name} section</h1>;
  }
}

class App extends React.Component {
  render() {
  return (
    <div>
     <Cat name=”Jim” />
    </div>
  );
  }
}

States

  • C'est limité au composant, modifiable et asynchrone:
class Cat extends React.Component {

 constructor(props) {
   super(props);
   this.state = {
	name: “Jim”
   };
 }

  render() {
    return <div>{ this.state.name }</div>;
  }
}

Nouvelle version

  • On est passé d'une approche Class component à une approche Functional component:
class Cat extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

devient

function Cat(props) {
    return <h1>Hello, {props.name}</h1>;
}

Cycle de Vie


             ┌─────────────────────────┐    ┌──────────────────────┐   ┌────────────────────────┐
             │                         │    │                      │   │                        │
             │   Mounting              │    │   Updating           │   │ Unmounting             │
             │                         │    │                      │   │                        │
             │                         │    │                      │   │     │                  │
             │   Constructor           │    │                      │   │     │                  │
             │                         │    │                      │   │     │                  │
             │         │               │    │                      │   │     │                  │
             │         │               │    │                      │   │     │                  │
             │         │               │    │                      │   │     │                  │
             │         │               │    │                      │   │     │                  │
             │    ┌────▼───────────────┼────┼─────────────┐        │   │     │                  │
             │    │                    │    │             │        │   │     │                  │
             │    │           render   │    │             │        │   │     │                  │
             │    │                    │    │             │        │   │     │                  │
             │    └────────┬───────────┼────┼────────┬────┘        │   │     │                  │
             │             │           │    │        │             │   │     │                  │
             │             │           │    │        │             │   │     ▼                  │
             │             ▼           │    │        ▼             │   │                        │
             │                         │    │                      │   │                        │
             │   ComponentDidMount     │    │ ComponentDidUpdate   │   │  ComponentDidUnmount   │
             │                         │    │                      │   │                        │
             │                         │    │                      │   │                        │
             └─────────────────────────┘    └──────────────────────┘   └────────────────────────┘


Code

Fragments

  • Permet de rendre des composants HTML au même niveau sans avoir besoin de "nested":
<>
    /* Mon code */
</>

est équivalent à

<Fragment>
/* Mon code */
</Fragment>

Keys

  • Penser à utiliser les keys dans les composant pour permettre à React de faire le rendu dans le bon sens.

Get Started

Pour créer une app React avec npx, on utilise Create React App (CRA) :

  npx create-react-app front --template typescript
  cd front
  npm start

Router

  • Avec react on peut avoir un router qui manipule l'API history du DOM Html. Le package à installer est le suivant: react-router-dom@6

Context

Les Context permettent de partager des données en profondeur dans l'arbre sans avoir besoin de passer les éléments à travers les props. Il possède deux éléments clefs:

  • Provider qui déclare et fournit les données du contexte.
  • Consumer qui conomme et récupère les données du contexte

Redux

  • Permet de faire ce que fait les Context avant leur introduction.
  • Il possède un état global appelé le Store.
  • C'est une _conteneur à état prédictible: en fonction des inputs, on peut prévoir l'état suivant.
  • Les actions sont déclenchées par les composants React et modifie l'état du Store
  • La réponse est produite et récupérée par un reducer qui fabrique un nouvel état du store à partir de l'état précédent et de la réponse de l'action.
  • Pour l'action, utilisation de fonctions pures : (pas de variations de sorties pour les mêmes arguments + pas d'effets de bord).
  • Les selectors permettent d'obtenir le resultat depuis le store.

Test

React Testing Library (RTL)

  • Permet d'interagir avec les composants React.

Smoke test

  • Permet de vérifier qu'un composant s'affiche sans crash.

Snapshot test

  • Vérifier si le rendu d'un html est bon.

Mock test

  • permet de vérifier que les composants s'affichent comme il le faut.

Formulaire

Uncontrolled vs controlled component

  • Les Uncontrolled components sont des composants qui sont gérés par le DOM html.
  • Les Controlled components sont des composants dont l'état interne est géré par React.

Uncontrolled

Pour faire un uncontrolled, on définit une référence que l'on donne en attribut :

// Valeur de input est accessible via nameInputRef.current.value
// Nous devons utiliser defaultValue pour initialiser l'input
function NameFormUncontrolled({defaultValue}: {defaultValue: string}) {
  const nameInputRef = useRef<HTMLInputElement>(null);
  return (
    <div>
      <input defaultValue={defaultValue} ref={nameInputRef} placeholder="name" />
    </div>
  );

Controlled

  • On récupère l'état interne via un State :
function NameFormControlled() {
  const [name, setName] = useState("");
  return (
    <div>
      <input
        onChange={(inputEvent) => setName(inputEvent.target.value)}
        defaultValue={name}
      />
    </div>
  );
}

React Hook Form

Il s'agit d"une bibliotèque permettant de construire un formulaire sans avoir trop de code redondant.

npm install react-hook-form