Aller au contenu principal

React JS

Packages

  • Package react ("platform-agnostic")
  • Puis des packages différents par plateforme. Chaque plateforme a ses propres primitives / éléments
    • react-dom (web ; primitives = éléments html)
    • react-native (mobile ; pas de div mais des primitives Text, View, Pressable,...)
    • react-three-fiber (scènes 3d ; primitives basées sur des formes et des textures)

Fonctionnement interne de React

  • (Si utilisation de JSX, le JSX est compilé en JS et convertit en utilisant createElement ci-dessous)
  • Création d'un élément React : React.createElement('p', {maProp: 'hello', 'Mon contenu ajouté en enfant'}
  • Element React = un objet js avec différentes propriétés (type, key, ref, props, _owner, _store)
  • Choix de la racine de l'app : root = createRoot(monElementHTML)
  • Puis on rend l'app : root.render(reactElement) (fonction render = convertit un élément react en node HTML)

JSX

  • Depuis React 17, l'outil qui compile jsx en js importe aussi React (avant ce n'était pas le cas donc on pouvait se retrouver avec React is not defined qui pouvait être confus vu que React n'est pas utilisé directement en jsx)
  • Etant donné que le JSX est transformé en js, on ne peut pas utiliser de mots réservés en js, dans notre jsx
    • Exemple : l'utilisation de for et class qui sont des mots réservés
    • Pour éviter cela, React utilise des variations : htmlFor, className
  • Contrairement à l'HTML :
    • tous les tags doivent être explicitement fermés, exemple : on ne peut pas faire <img src="">
    • les tags sont sensible à la casse (techniquement cet html est valide <HEADER>, mais en jsx ce n'est pas le cas)
    • Les attributs doivent être en camelCase (exemple: tabIndex) SAUF les attributs data- et aria- qui gardent bien leurs tirets
    • l'attribut style ne prend pas une string mais un objet avec les propriétés en camelCase style={{fontSize: '2rem'}}

Cheat sheet

  • Evenements
    • en camelCase, on passe une fonction et pas une string
    • Exemple : onClick={activateLasers}
    • Pour passer des args, fonction wrapper : onClick={() => activateLasers(myParam)}
    • Les événements personnalisés sont des props ajoutés au composant (la fonction est passée en param en callback)
  • State : variables/état interne au composant sous forme de class.(this.state)
    • Initialisation du state dans le constructeur
    • Pour ajouter des variables qui sont pas utilisée dans l'ui, je peux les ajouter directement sur l'instance de la classe (exemple this.timerId)
    • MAJ le state : this.setState({}) (on ne modifie pas le state directement !!). Les MAJ sont mergées donc on peut setter juste la propriété qui nous intéresse.
    • les setters de state ne sont pas immédiats, mais asynchrones. Donc le setState agit sur le prochain rendu !! Si on a une fonction onClick qui contient de la logique après le setState, cela se fera sur la précédente valeur du state si on utilise le state.
    • Attention les changements doivent être immutable, si on modifie le state on doit fournir un nouvel array et pas muter un array existant
    • La seule manière de passer le state à l'intérieur d'une app est d'utiliser les props
  • Render
    • Chaque re-render commence par un changement dans le state => ne re-render pas toute l'application, juste le composant et tous ses descendants

Hooks

  • Fonctions React qui commencent par use. Peuvent être uniquement appelés dans un composant React et ne peuvent pas être appelés conditionnellement (car sinon l'ordre des appels de fonctions peut être changé).
  • useState => const [maVar, setMaVar] = useState(maValeurParDefaut)
    • useState peut aussi prendre une fonction en param
  • useId : permet de créer un id unique sur l'instance du composant, qui va s'incrémenter avec le nb d'instance. Permet d'avoir toujours avoir un id unique sur la page (même valeur entre rendu client et serveur)
  • useEffect : se lance après le render d'un composant, permet de récupérer des informations après render. En "Strict Mode", UseEffect se lance deux fois après le premier mounted. (car en strict mode on vient lancer plusieurs fois certains bouts de code)
  • useRef : même fonctionnement de ref que VueJS (référence d'un élément du DOM). Utilisation : const canvasRef = React.useRef(); et <div ref={canvasRef}></div>

Optimisation de React

De manière générale, si les MAJ du state sont lentes, vérifier que :

  • je suis sur un build de prod (car les build dev sont intentionnellement plus lents)
  • Vérifier que je n'ai pas mis le state plus haut dans l'arbre que nécessaire
  • Lancer le React DevTools Profiler pour voir ce qui est re-rendu, et wrapper les arbres les plus "chers" avec memo() (utiliser useMemo() là où il y a besoin)

Sources