Syntaxes avancées sur les objets
Comme on l'a vu précédemment, un objet Javascript se comporte en grande partie comme un dictionnaire, et peut être utilisé dans de multiples situations.
Syntaxe abrégée
La syntaxe normale d'un objet littéral est {k1: v1, k2: v2, ...}
, cependant il est fréquent d'observer une
syntaxe différente :
{a, b, c}
équivaut à {a: a, b: b, c: c}
, autrement dit :
- clé
"a"
-> valeur de la variablea
- clé
"b"
-> valeur de la variableb
- clé
"c"
-> valeur de la variablec
Les deux syntaxes peuvent être mélangées au sein d'un même objet, par exemple :
qui équivaut à :
Attention : ne pas confondre cette notation avec l'usage de {}
dans JSX !
Affectation par décomposition ("destructuring assignment")
Ce terme désigne la possibilité d'extraire les données d'un objet ou d'une liste dans des variables distinctes.
Les exemples ci-dessous proviennent de la documentation MDN (Mozilla Developer Network) :
let a, b, rest;
// Tableaux
[a, b] = [10, 20];
[a, b, ...rest] = [10, 20, 30, 40, 50];
// Objets
({a, b} = {a: 10, b: 20});
({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
Dans tous ces exemples, les variables a
et b
reçoivent 10
et 20
respectivement.
Note : la syntaxe ...rest
fait appel à l'"opérateur de décomposition".
Utilisation de cette syntaxe dans les fonctions
En entrée
Une fonction peut prendre en entrée un unique objet (comme props
), et le destructurer. Cette syntaxe permet
de simuler des paramètres nominatifs, absents en Javascript :
Une syntaxe alternative permet de faire apparaître x et y explicitement :
Dans cet exemple particulier, l'intérêt semble limité (pourquoi ne pas utiliser simplement distance_l2(x,y)
?),
cependant elle est très utile en React, notamment pour définir et appeler des composants.
Note : Javascript ne permet pas de définir des arguments de fonction nominatifs comme Python. L'utilisation d'objets comme arguments permet de retrouver une fonctionnalité équivalente.
En sortie
Une fonction peut également renvoyer ses résultats sous forme d'un objet. Dans ce cas, on peut utiliser tout ou partie du résultat, en fonction de ses besoins.
Exemple 1
Supposons qu'on ait défini un contexte React qui stocke différentes informations : * utilisateur authentifié * token de l'utilisateur authentifié * langue de l'application * ...
On peut récupérer uniquement les parties qui nous intéressent pour un traitement donné :
import { useContext } from "react";
// L'objet ctx contient des données de contexte, partagées vers tous les composants de l'application
const ctx = useContext(...);
console.log(ctx.user);
// Si on s'intéresse uniquement à une donnée, on peut écrire, par exemple
const { user } = useContext(...); // On veut uniquement l'utilisateur en cours
const { token } = useContext(...); // On veut uniquement le token de l'utilisateur
const { locale } = useContext(...); // On veut uniquement la locale (langue en cours)
const { user, locale } = useContext(...); // On veut l'utilisateur et la locale
Si la fonction est définie comme :
alors on peut l'appeler par :
const { locale } = useContext(...); // On récupère seulement une partie du contexte
setLocale({locale})
voire :
const ctx = useContext(...); // on récupère tout le contexte...
setLocale(ctx); //...mais la fonction utilisera seulement la partie qui l'intéresse, { locale }
Exemple 2 : SWR
import useSWR from 'swr'
function Profile() {
const { data, error, isLoading } = useSWR('/api/user')
if (error) return <div>failed to load</div>
if (isLoading) return <div>loading...</div>
return <div>hello {data.name}!</div>
}
Le module SWR définit le hook useSWR
, qui appelle une URL et renvoie un objet contenant
différents éléments :
data
: les données reçueserror
: erreur éventuellement survenueisLoading
: un booléen qui indique si les données sont toujours en train de se chargermutate
: une fonction qui permet de signaler à SWR de recharger les données- ...
En fonction de ses besoins, on peut utiliser seulement une partie des données :
ou bien, si on a besoin de pouvoir recharger les données à la demande :
Exemple 3 : react-hook-form
React-hook-form est un module qui simplifie très grandement la gestion des
formulaires en React, par le biais d'un hook, useForm
.
Version minimale :
Version permettant de récupérer en plus les erreurs de validation, et de les afficher :
const { register, handleSubmit, formState: { errors } } = useForm(
{ resolver: yupResolver(editUserSchema) });
Conclusion
L'utilisation de la syntaxe simplifiée et de l'affectation par décomposition fournit une très grande souplesse et expressivité du code. La base de Javascript est extrêmement primitive, mais les évolutions modernes en font un langage beaucoup plus intéressant.
Les composants React étant écrits sous forme de fonctions, on pourra mettre à profit ces syntaxes lors de leur écriture.