JavaScript : 7 Choses à connaitre pour React

Il y a un pas à franchir entre les bases de JavaScript et ce dont vous avez besoin pour comprendre comment coder dans React. Le fossé n'est pas immense, mais il est suffisemment grand pour qu'il vaille la peine de l'expliciter. Voici donc 7 compétences JavaScript utiles pour coder en React.

Nous allons voir ensemble comment elles apparaissent dans React, et comment elles peuvent nous être utiles.

Et même si React vous intéresse pas, ces concepts sont utiles pour coder en JavaScript.

Mais d'abord un point rapide et néanmoins fondamental.

Parlons des valeurs « Falsy » et « Truthy »

Le JavaScript considère certaines valeurs comme "presque fausses" ou « falsy ». Bien que ces valeurs ne soient pas strictement égales à la booléenne false, elles ne passent pas une évaluation dans une condition if.

Pour dire les choses autrement, en termes de logique JavaScript considère ces valeurs comme fausses.

Les valeurs falsy en JavaScript incluent (entre autres) : • undefined • null • la chaîne vide • le chiffre 0 • et NaN (ou Not a Number)

Les valeurs qui ne sont pas « falsy » sont « truthy » : le JavaScript considère qu’elles sont « comme si elles étaient vraies ».

Cette précision va être utile pour comprendre les opérateurs booléens et l'opérateur ternaire...

Parlons tout d'abord Opérateurs booléens

Vous êtes sans doute familier avec l'utilisation des opérateurs booléens && et || dans les conditions. JavaScript permet de faire bien plus que cela. Pourquoi ? Parce que ces opérateurs ne renvoient pas toujours une valeur booléenne.

Laissez-moi vous expliquer.

Commençons par l'opérateur booléen ou (||). Celui-ci évalue le premier élément de l'expression, à gauche, et regarde s'il est "falsy" ou non. Si la valeur est "truthy", l'opérateur renvoie ce premier terme. Sinon, il renvoie le second, à droite de l'opérateur.

Imaginons que nous ayons une variable (par exemple, « name »). On ne savons pas si elle est définie ou non. Si elle n'est pas définie, nous voulons lui affecter une valeur par défaut. L'opérateur || nous permet de faire ce qui suit :

 name = name || "defaultName" ;

Si name est undefined, ou null, ou la chaîne vide, l'opérateur retournera le deuxième terme : ici, "defaultName". Si à l’inverse "name" est défini, il sera retourné par l'opérateur. Ça nous permet donc d'assigner une valeur par défaut.

L'opérateur booléen && a exactement le comportement inverse que l'opérateur ||. C'est à dire: si le premier terme est "truthy", l'opérateur && renvoie le deuxième terme (là où || renvoie le premier)

Voyons comment utiliser cela dans React. Imaginons par exemple que nous avons une variable appelée errorMessage . Elle peut contenir ou non un message d'erreur.

Dans la partie JSX de notre code, dans React, nous pouvons écrire quelque chose comme ceci :

{errorMessage && <span>{errorMessage}</span>}

Dans ce cas, l'opérateur && ne renvoie le span que si la variable errorMessage est truthy. Autrement dit, nous n'affichons le span que s'il y a un message d'erreur.

Parlon à présent de :

L'opérateur ternaire

Il existe sorte d'instruction if / else condensée appelée opérateur ternaire. Il s'écrit avec un point d'interrogation et un signe deux-points :

variableIsTruthy ? itIsTrue : itIsFalse

L'opérateur vérifie si le premier terme est "truthy". Si c'est le cas, l'opérateur renvoie le deuxième terme, situé après le point d'interrogation.

Si ce n'est pas le cas, il renvoie le troisième terme, situé après les deux points.

Dans notre exemple d'erreur, si nous voulons également afficher un message en l'absence d'erreur, nous écrire ajouter ce qui suit à notre code JSX :

{ error ? <span>{error}</span> : <span>Il n'y a pas d'erreur</span>}

Bien sûr, dans ce cas précis, nous aurions pu l'écrire plus simplement à l'intérieur du span :

<span>{error ? error : "There is no error"}</span>

... mais seulement parce que je n'ai pas pris la peine d'ajouter un quelconque style au span pour l'erreur.

Déstructuration de tableaux et d'objets

Examinons un simple hook useState.

const [counter, setCounter] = useState(0) ;

Regardez comment les variables counter et setCounter sont définies, à l'intérieur d'un tableau. Le hook renvoie un array. Cette syntaxe attribue la première valeur du tableau à la première variable et la seconde à la seconde.

C'est une façon plus courte (et plus élégante) d'écrire :

const temp = useState(0) ;
const counter = temp[0] ;
const setCounter = temp[1] ;

La syntaxe de déstructuration est beaucoup plus concise et permet de se passer de la variable temporaire. La syntaxe pour les objets est similaire. Elle se rencontre généralement en premier dans les déclarations d'importation. Par exemple

import { useState } from 'react' ;

Comment cela fonctionne-t-il ? Imaginons que nous avons un objet utilisateur avec un âge et un nom :

const user = {
  nom : "Bob", 
  age : 42
}

Nous pouvons récupérer le nom directement en utilisant la déstructuration :

const {nom} = utilisateur ;

Cela reviendrait à

const name = user.name ;

La fonction flèche

La fonction flèche est une façon plus concise d'écrire des fonctions. Dans React, être concis aide souvent à écrire du code plus lisible. Les fonctions flèche sont également le moyen naturel d'écrire des hooks useEffect.

En guise de récapitulatif rapide : la manière "normale" d'écrire une fonction est d'utiliser le mot-clé function. ex :

fonction add(a,b) {
  retourne a + b ;
}

Nous pouvons écrire ceci comme une fonction flèche en déclarant :

const add = (a,b) => {
  retourne a + b ;
}

En fait, comme il n'y a qu'une instruction de retour dans cette fonction, nous pouvons supprimer les parenthèses et l'instruction de retour elle-même :

const add = (a,b) => a + b

Ceci est particulièrement utile lorsque vous utilisez les fonctions des Array.

Les fonctions des Array, en particulier map et filter

Les tableaux disposent de fonctions intéressantes qui peuvent opérer sur eux. Il y en a deux en particulier que je trouve particulièrement utiles dans le contexte de React : map et filter.

Elles prennent toutes deux une fonction en paramètre et renvoient un nouveau tableau.

Filter renvoie un tableau qui ne contient que les éléments pour lesquels la fonction passée en paramètre renvoie une valeur véridique.

Si nous filtrons un tableau de nombres par la fonction qui renvoie modulo 2, notre nouveau tableau ne contient plus que des nombres impairs. En effet, les nombres pairs renvoient 0 lorsqu'ils sont soumis à la fonction modulo, et 0 est faux :

const odd = [1, 2, 4, 7, 9, 22].filter((a) => a % 2) ;
// odd n'a maintenant que des nombres impairs : [1, 7, 9]

Map, lui, renvoie un tableau où chaque nouvel élément est la valeur de retour de la fonction. Si nous passons une fonction qui multiplie son entrée par 2, la sortie est un tableau de doubles de l'entrée.

const double = [1, 2, 4, 7, 9, 22].map((a) => a * 2) ;
// double a maintenant des doubles :  [2, 4, 8, 14, 18, 44]

En quoi cela est-il utile dans React ? Disons que nous construisons une application de liste de tâches. Nous avons un tableau de tâches que nous voulons afficher, stocké dans une variable tasks. Chaque élément possède (par exemple) :

  • un ID,
  • un titre,
  • un état complété, qui peut être vrai ou faux.

Disons également que nous avons défini un composant Task. Nous pouvons créer une liste en utilisant la fonction map pour retourner un composant de tâche pour chaque élément :

{ tasks.map((task) => <Task key={task.id} task={task} /> }

Nous pouvons afficher uniquement les éléments incomplets en utilisant un filtre pour masquer les éléments où complete est vrai :

{ 
tasks.filter(task => !item.complete).map((task) => <Task key={task.id} task={task} /> 
}

(Petite parenthèse : nous devons spécifier une valeur de clé pour aider React à suivre exactement ce qui a été modifié).

Il existe de nombreuses autres fonctions de tableau utiles qui méritent d'être mentionnées. Le sujet mérite un traitement plus approfondi. Mais ce sont les deux que je trouve les plus utiles.

L'opérateur d'étalement (ou de spread)

Si vous utilisez des objets dans votre état, vous devrez commencer à utiliser l'opérateur d'étalement. L'opérateur spread nous permet de créer un objet dupliqué avec toutes les mêmes valeurs.

const user = {
  nom : "Bob", 
  age : 42
}

const user1 = utilisateur ;
const user2 = {...utilisateur} ;

console.log(user == user1) ; // true 
console.log(user == user2) ; // false

Pourquoi est-ce utile ? React suit les changements pour savoir quand il faut rendre à nouveau des parties de l'arbre des composants. Dans l'exemple ci-dessus, user et user1 sont le même objet. Si nous définissons par exemple la propriété age à 43 sur user1, user1 sera toujours égal à user. Maintenant, imaginez que React suive l'état de l'objet user. Changer la valeur d'une des propriétés de l'objet user ne déclenchera pas la détection d'un changement d'état. Disons que nous avons une fonction setUser destinée à mettre à jour l'état de l'utilisateur. Si nous le faisons

user.age = 43 ;
setUser(user) ;

Cela ne déclenchera pas la détection du changement. User est toujours exactement le même objet. Nous devons créer un nouvel objet en utilisant l'opérateur d'étalement, et donc faire :

setUser({...utilisateur, age : 43}) ;

Que se passe-t-il ici ? Les deux accolades signifient que nous avons créé un nouvel objet. L'opérateur d'étalement agit comme s'il divisait (ou étalait) l'objet initial. Si nous devions écrire explicitement ce qui se passe ici... Ce serait particulièrement long. Nous devons d'abord créer un nouvel objet vierge. Puis nous listons toutes les clés de l'objet utilisateur. Puis nous itérons sur la liste des clés. Ce faisant, nous fixons la valeur de la propriété dans le nouvel objet à la valeur correspondante dans l'ancien objet. Enfin, nous définissons la nouvelle valeur modifiée.

const newUser = {}
let keys = Object.keys(user) ;

for(let i = 0 ; i < keys.length ; i++) {
	let key = keys[i] ;
	newUser[key] = user[key] ;
}

newUser.age = 43 ;

C'est très loin d'être concis.

L'opérateur d'étalement ou de spread condense tout cela en une seule ligne. Et le code qui en résulte est aussi lisible (si ce n'est plus) une fois que vous avez compris ce qu'il signifie.

Pour aller plus loin

N'oubliez pas : l'utilisation des fonctionnalités avancées d'un langage ne doit jamais primer sur la lisibilité. Cependant, si elles sont utilisées correctement, ces fonctionnalités contribuent à rendre votre code plus lisible, pas moins.

Qu'y a-t-il d'autre à maîtriser, à continuer à apprendre ?

Tout d'abord, il est vital de comprendre le fonctionnement des Promesses et d'async/await. Ce n'est pas une partie essentielle de React. Il existe des hooks qui cachent la complexité pour vous. Mais si vous voulez maîtriser JavaScript, c'est inévitable.

Si vous souhaitez maîtriser React, vous devez comprendre le fonctionnement des hooks, et les erreurs de débutant à éviter.

Social
Made by kodaps · All rights reserved.
© 2023