Les nouveautés et nouvelles qu'il ne fallait pas manquer sur l'écosystème React / Javascript, de Mai 2022 🤗
Au programme ce mois-ci :
- Une nouvelle proposition de hook
useEvent
- Storybook: Webpack vs Vite
- Un nouveau système de routing pour NextJS
- Les packages / librairies / outils à surveiller
- Et on termine par le WTF JS?
Un nouveau hook useEvent
?
useEvent
serait un nouvel hook, sans tableau de dépendance, qui permet d'avoir une référence persistante à une fonction, et qui utiliserait toujours la valeur courante des variables dans son corps d'exécution. Bon. Une fois ça dit, concrètement à quoi ça sert, et comment ça se matérialise ?
Revenons un peu en arrière, sur comment marche la comparaison de props en React. J'ai déjà écris un article dessus
const Cart = () => {
const [total, setTotal] = useState(0);
const onClickBuy = {
console.log(total);
};
return (
...
<BuyButton onClick={onClickBuy} />
);
}
Dans l'exemple ci-dessous, nous aurons notre bouton BuyButton
qui sera re-render à chaque render de notre Cart
car la fonction onClickBuy
est redéfinie à chaque fois. Pour changer ca, nous utilisons actuellement useCallback
const Cart = () => {
const [total, setTotal] = useState(0);
const onClickBuy = useCallback(() => {
console.log(total);
}, [total]);
return (
...
<BuyButton onClick={onClickBuy} />
);
}
Nous avions donc dans notre tableau de dépendance de useCallback
le total
. Ce qui veut dire qu'à chaque fois que ce total
change, onClickBuy
est redéfini, et donc BuyButton
sera également re-render.
Si nous omettons total
dans notre tableau de dépendance, onClickBuy
ne sera jamais redéfini, mais la valeur de total
est figée lors de la définition de la fonction. C'est à dire que même si vous faites varier le total pour avoir 10
, onClickBuy
affichera toujours 0
, la valeur initiale de total
lorsque onClickBuy
a été définie.
Alors useEvent
donc ?
const Cart = () => {
const [total, setTotal] = useState(0);
const onClickBuy = useEvent(() => {
console.log(total);
});
return (
...
<BuyButton onClick={onClickBuy} />
);
}
useEvent
est donc sans tableau de dépendance (comme vous pouvez le voir)useEvent
permet d'avoir une référence persistante. C'est à dire qu'à chaque re-render de notre Cart, onClickBuy ne sera PAS redéfini, et donc BuyButton ne sera pas re-renderuseEvent
utilise toujours la valeur courante des variables. Ce qui veut dire quetotal
ici sera bien la valeur courante detotal
et non pas la valeur detotal
au moment de la définition deonClickBuy
Alors est-ce la fin de useCallback
? Pas tout à fait. Très clairement une grande quantité de useCallback
va pouvoir être transformé en useEvent
. Mais useCallback
DEVRA être conservé lorsque vous retournez du JSX
. J'aurai certainement l'occasion d'en reparler plus tard.
Si vous souhaitez en lire plus sur cet RFC, ca se passe par ici !
StoryBook : Webpack vs ViteJS
Après Gatsby, c'est au tour de Storybook de se questionner sur Webpack vs ViteJS. Et le moins que l'on puisse dire, c'est que le résultat de leur benchmark est... surprenant !
En effet, ViteJS et à chaque fois moins performant que Webpack (sauf pour le HMR). Storybook compte proposer aux développeurs d'utiliser Webpack ou ViteJS comme ils veulent via la configuration.
Pour lire tout le benchmark, c'est par ici !
Proposition d'un nouveau système de routing pour NextJS
NextJS souhaite changer son système de routing, pour tirer parti des dernières fonctionnalités de React18
, et des ServerComponents
Ce changement leur permettrait également de grouper les potentiels fetch
plutot que de les executer en cascade, un peu comme le propose Remix
Pour ce faire, ils proposent de continuer à garder le répertoire /pages
qui sert actuellement au routing, et de rajouter un répertoire /app
qui activerait automatiquement la nouvelle architecture. Les 2 systèmes seraient viable en parallèle pour permettre une adaptation (et adoption) incrémentale de votre code.
Cette RFC est annoncée comme la plus grosse mise à jour de NextJS depuis sa création en 2016, et on devrait en savoir plus également rapidement. Pour en lire plus à ce sujet, c'est par ici !
Packages / Librairies
- FortuneSheet Une spreadsheet (Google Sheet / Excel like) comme simple composant React, qui a l'air bien poussé.
- Loaders Des loaders / spinners, légers et configurables, le tout en composants React.
- useClampText Un hook pour générer facilement des "voir plus" sur des textes, qui prend en compte le multiligne.
- ReactTable passe en
v8
et devient TanStack Table - Antares SQL. Client SQL open source et gratuit. Une bonne alternative au performant (mais payant) TablePlus
- IT Tools Une toolbook pour l'IT qui permet de faire... plein de choses ! Des générateurs en tout genre (token, qr code,...), convertisseurs (couleur, casse, base64,...)
WTF JS?
Que va afficher ce console.log
?
Math.min() > Math.max();
Afficher la solution et les explications !
😱 true
😱
Alors pourquoi ?
Et bien il faut comprendre comment marchent ces fonctions Math.min
et Math.max
. Prenons Math.min
, il va comparer tous les nombres passés en arguments pour définir lequel est le plus petit. En gros une petite boucle (simplifiée évidemment) dans le genre :
const totalArguments = arguments.length;
let min = ?; // On verra ca plus tard :)
for (i = 0; i<totalArguments; i++) {
if (arguments[i] < min) min = arguments[i];
}
Mais comment initialiser ce min
pour effectuer la première comparaison ? Pour être sûr que le premier argument satisfasse toujours la condition, et soit donc le nouveau min
? On aurait pu penser qu'une simple condition aurait suffit :
const totalArguments = arguments.length;
let min;
for (i = 0; i<totalArguments; i++) {
if (i === 0) min = arguments[i];
else {
if (arguments[i] < min) min = arguments[i];
}
}
Mais ce n'est pas ce qui a été fait, ce min
est initialisé à... Infinity
. Donc en effet, quel que soit le nombre que vous passez comme argument, ca sera toujours plus petit que Infinity
!
Sauf que si on ne passe aucun argument à notre fonction... et bien Math.min()
retourne Infinity
.
Et de la même façon (mais dans l'autre sens), Math.max
retourne -Infinity
si appelé sans argument.
Et Infinity > -Infinity
, donc Math.min() > Math.max()
🤘
Ne manquez pas un article !
Envie de recevoir par email mes derniers articles et Recapt ?
Essayez de taper register <votre adresse email>
dans la console 🎉