Fermer

février 8, 2024

Comment les frameworks JavaScript partagent des données entre les composants

Comment les frameworks JavaScript partagent des données entre les composants


Les singletons peuvent être une solution courante pour partager des données entre composants, mais sont-ils sécurisés ? Réponse courte, non. Voyons ensuite comment les différents frameworks JS gèrent les données.

Si vous souhaitez partager des données entre vos composants, la première chose à laquelle vous pourriez penser est un singleton. Un singleton est une instance unique d’un objet. En JavaScript, un objet peut être une fonction ou une classe. Cependant, les singletons ne constituent pas toujours un cas d’utilisation parfait pour le partage d’état.

Un exemple singleton

partagé.ts

export const shared = new Map();

Je peux en partager un seul shared objet sur plusieurs composants. Cela fonctionne essentiellement comme un global. Partout où une variable peut être importée, elle peut être utilisée et l’état reste le même. Si l’objet est mis à jour dans le composant 1, les données persisteront dans le composant 2 jusqu’à ce que l’application soit détruite.

composant1.tsx

import { shared } from 'shared.ts';

// ... somewhere in template

shared.set('key', 'value');

composant2.tsx

import { shared } from 'shared.ts';

// ... somewhere in template

const value = shared.get('key');

Cela pourrait fonctionner dans Svelte, Angular, React ou dans n’importe quel composant de n’importe quel framework JavaScript.

Mais …

Le problème mondial

Les singletons sont des globaux. Ce n’est PAS une bonne chose pour le rendu côté serveur, et cela ne vous permet PAS de créer des modèles de données réutilisables comme des services ou des magasins sur le serveur. Si vous exécutiez ce code sur le serveur, chaque client pourrait avoir accès à votre valeur partagée. Ce n’est pas sécurisé. Alors, comment éviter cela ?

Pour aider à résoudre ce problème, il est important de comprendre que chaque objet JS est transmis par référence et non par valeur.

// delcare object x
const x = { test: 'value' };

// declare function y
function y(p: { test: string }) {
	p.test="new value";

	console.log(x);
}

// run function y
y(x);

Si nous exécutons ce code, nous verrons que même si nous n’avons pas mis à jour x directement, sa valeur a encore été modifiée. Le x l’objet a été passé par référence.

Il convient également de noter que toutes les valeurs parentales sont disponibles pour les enfants en JavaScript :

function v() {

    const x = 'me';

    function y() {

      function z() {
        console.log(x);
      }
      z();
    };
    y();
  }
  v();

Cela fonctionne comme prévu, et le x la valeur ne figure pas dans l’espace de noms global supérieur. C’est ainsi que nous devons l’écrire pour empêcher les déclarations de variables globales. Mais comment cela fonctionne-t-il dans les cadres réels ?

Fournisseurs

Un fournisseur dans un framework fournit une instance d’un objet à un composant. Cela signifie qu’il transmet l’instance de cet objet aux fonctions de ses enfants. Un composant est essentiellement simplement une fonction, une classe ou un objet, au sein d’une classe de fonctions ou d’un objet. Le fournisseur fournit un singleton qui peut être partagé dans votre application.

Cela peut être appelé différemment dans tous les frameworks, mais le principe est le même : fournir un singleton que les composants de votre application peuvent partager.

Angulaire

Les fournisseurs d’Angular utilisent des services et des injecteurs. C’est appelé Injection de dépendance d’Angular Système. Il transmet simplement l’instance de la fonction, de l’objet ou de la classe au composant. Vous verrez généralement simplement une classe partagée (appelée service) en tant que fournisseur. C’est très personnalisable.

Réagir

Ce cadre fonctionne un peu différemment. React partage un état global mis à la disposition des composants à l’aide du contexte. Le createContext l’objet doit être partagé avec le fournisseur et useContext (consommateur). Cela signifie que les contextes d’une variable globale ne sont disponibles que pour les composants qui les consomment. Cette variable globale enregistre tous les contextes. Next.js et Remix empêchent la variable globale de fuir.

SolidJS

Solid utilise le même modèle que React, avec createContext et useContext. Après tout, SolidJS est l’enfant génétiquement modifié de React : les ingénieurs ont tout simplement oublié de faciliter la gestion du contexte.

Svelte

Svelte est génial dans la mesure où il crée automatiquement un nouveau contexte pour chaque composant, héritant de tout son contexte parent. Cela signifie getContext et setContext font exactement cela : le forage automatique des hélices.

Cependant, la manière recommandée de partager un writable sur le client n’est pas recommandé pour SvelteKit, car il s’agit simplement d’un fichier global. Voir mon article : La bonne façon d’utiliser les magasins dans SvelteKit.

Vue

Vue utilise provide et injectqui est une combinaison de techniques Angular et React, mais avec moins de maux de tête.

Rapide

Qwik n’a malheureusement pas appris des erreurs de React, et vous oblige à déclarer manuellement un contexte de fournisseur pour chaque composant. Cependant, contrairement à React, vous n’avez pas besoin de créer un Arborescence des composants HTMLcar cela se fait automatiquement.

Je n’ai toujours pas aimé ça dans Qwik, alors j’ai créé un fichier personnalisé useShared accroche-toi à mon Exemple d’application de menu. J’espère que ces modèles de conception deviendront la norme et seront automatiquement intégrés aux futures versions du framework.

Résumé

  • Les données sont toujours partagées dans un objet global ou un objet parent. Cet objet est référencé par un composant enfant (objet/fonction/classe) en le passant directement par référence, ou en faisant simplement référence à l’objet global partagé.
  • N’exportez pas directement un objet et n’appelez pas une fonction au niveau global si vous utilisez le rendu côté serveur. Cela rendra les données disponibles pour tous les utilisateurs de ce serveur.

Il existe de nombreux paradigmes pour partager des données entre nos composants, mais j’aime la simplicité de Svelte. Cela deviendra peut-être plus facile dans les futures versions du framework. Quoi qu’il en soit, faites attention à la manière dont vous gérez vos données partagées.




Source link