Stockage des valeurs
Il existe plusieurs formes de stockage dans les navigateurs modernes. Voici un aperçu de ces formes de stockage et des cas dans lesquels elles doivent être privilégiées.
En mémoire
En général, le stockage en mémoire fait référence à tout ce qui est stocké en JavaScript et qui ne fait pas partie d’un stockage persistant. Les valeurs stockées en mémoire restent valables pendant:
| Type | Durée |
|---|---|
| Variable | Champ d’application de la variable |
| React State | Cycle de vie d’un composant |
| React Memo | Cycle de vie du composant |
| React Context | Cycle de vie de la sous-arborescence React |
| Global Store (en mémoire) | Jusqu’au rechargement de la page |
Aucune valeur en mémoire ne survit au rechargement de la page. Pour les valeurs qui doivent persister après un rechargement de page (et notez que cela signifie un rafraîchissement de la page du navigateur et pas seulement une navigation dans l’application), utilisez le stockage persistant ou un global store adossé à sessionStorage.
Variables
Moyen le plus simple de stocker une valeur. Cela ressemble à quelque chose comme
const value = /* une valeur */;Le cycle de vie de cette variable dépend de sa portée . En général, il est préférable de stocker les valeurs dans la portée la plus étroite possible, c’est-à-dire de préférer la portée de la fonction à la portée du module et la portée du module à la portée globale.
Dans React, il est généralement préférable d’utiliser des variables simples, à moins que le recalcul de la variable ne soit coûteux. Par exemple:
const name = `${patient.first} ${patient.last}`;Cela devrait convenir, à moins d’opérer sur une grande liste d’éléments ou d’effectuer des opérations potentiellement compliquées.
État React
const [value, setValue] = useState(/* some value */);Parfois, nous avons besoin de variables qui conservent des valeurs cohérentes à travers les rendus des composants. Lorsque ces valeurs sont spécifiques à un composant, useState() nous permet de stocker une version spécifique à un composant d’une valeur qui n’est mise à jour que lorsque le setter est appelé.
React Memo
const value = useMemo(() => /* un calcul */, [dependencies]);Ce n’est pas exactement un “stockage”, mais comme useState() fournit une valeur cohérente jusqu’à ce qu’une condition soit remplie (une valeur dans le tableau de dépendances change). Utile pour les états rarement calculés ou coûteux à calculer.
Contexte React
Le mécanisme Contexte de React peut être utile pour stocker des données qui doivent être partagées uniquement par des composants dans le même arbre React; par exemple, les valeurs qui sont partagées par plusieurs composants dans le même microfrontend peuvent bénéficier de l’utilisation du contexte de React. Le contexte React fournit des valeurs dont la portée dépasse le cycle de vie d’un seul composant, mais qui ne sont pas maintenues en l’absence de l’arbre React. Par exemple, un formulaire peut utiliser React Context pour stocker toutes les valeurs “actuelles” de tous les composants d’entrée du formulaire.
// dans un module parent
const MyContext = createContext(/* some value */);
// dans un composant parent
return <MyContext.Provider value={/* some value */}>{children}</MyContext.Provider>;
// à l'intérieur d'un composant enfant
const myValue = useContext(MyContext);Ceci est utile pour s’assurer que tout un arbre React a une version cohérente de l’état.
Global Store
Fourni par @openmrs/esm-framework (spécifiquement, esm-state); cela nous donne accès aux Zustand stores . Ceci est utile pour stocker des valeurs qui sont partagées entre plusieurs composants et qui doivent être cohérentes entre elles. Notez que bien que l’implémentation sous-jacente utilise Zustand, il est préférable d’utiliser les API fournies par le framework, comme createGlobalStore et useStore, par exemple,
import { createGlobalStore, useStore } from "@openmrs/esm-framework";
interface User {
uuid: string;
display: string;
}
interface UserStore {
user: User | null;
}
// à l'extérieur d'un composant
const userStore = createGlobalStore<UserStore>("userStore", { user: null });
// à l'intérieur d'un composant
const { user } = useStore(userStore);
// à un autre moment
userStore.setState({ user: /* valeur provenant de quelque part */ });
// ou en utilisant une mise à jour fonctionnelle:
userStore.setState((state) => ({ ...state, user: /* valeur provenant de quelque part */ }));La mise à jour du magasin en utilisant setState() mettra à jour toutes les variables souscrites au magasin, y compris (comme dans l’exemple) user.
Les global stores sont en mémoire par défaut. Si un store doit survivre à un rafraîchissement du navigateur dans la même session d’onglet, passez "sessionStorage" comme troisième argument à createGlobalStore().
App context
App Context est un mécanisme de partage d’état entre différentes parties de l’application. Il est global par namespace, donc toute application peut lire un namespace enregistré, mais ce namespace appartient au composant qui le définit et il est supprimé lorsque ce composant est démonté.
Les cas d’utilisation courants d’App Context incluent:
- Partager de l’état entre des composants qui existent dans différents arbres React.
- Gérer un état temporaire partagé qui ne doit exister que pendant que certains composants sont actifs.
- Coordonner différentes parties d’une fonctionnalité, par exemple partager les données du patient sélectionné entre des composants liés.
Le framework fournit deux hooks pour travailler avec App Context:
- useDefineAppContext pour définir le contexte.
- useAppContext pour accéder au contexte.
Définir un contexte
const [dateRange, setDateRange] = useState<Date[]>([
dayjs().startOf("day").toDate(),
new Date(),
]);
useDefineAppContext<DateFilterContext>("laboratory-date-filter", {
dateRange,
setDateRange,
});useDefineAppContext() supprime le namespace lorsque le composant qui le définit est démonté. Les valeurs d’app context doivent utiliser null plutôt que undefined lorsqu’elles doivent représenter une valeur vide.
Accéder au contexte
const dateFilterContext = useAppContext<DateFilterContext>("laboratory-date-filter");
if (!dateFilterContext) {
return null;
}
const { dateRange, setDateRange } = dateFilterContext;Quand utiliser App Context plutôt qu’un Global Store
- Utilisez App Context quand vous devez partager un état qui ne doit exister que pendant que le composant qui le possède est monté.
- Utilisez Global Store quand vous avez besoin que l’état persiste entre les rendus de composants ou pendant tout le cycle de vie de l’application.
Stockage persistant
Le stockage persistant fait référence à tout mécanisme de stockage qui persiste au-delà du rendu de la page unique.
Le backend
Au moins en ligne, le stockage des données persistantes dans le backend devrait être la valeur par défaut. Cela se fait généralement en utilisant les API REST ou FHIR pour OpenMRS.
Stockage de session
Il s’agit d’une API Storage pour les valeurs qui persistent à travers une page session. Les sessions de page persistent généralement aussi longtemps qu’un seul onglet du navigateur. Il s’agit du mécanisme de stockage privilégié pour les valeurs qui doivent persister au-delà de la limite de rechargement de la page.
Stockage local
Il s’agit d’une API Storage pour les valeurs qui persistent jusqu’à ce qu’elles soient modifiées. Elles sont spécifiques à une origine web, mais s’appliquent à tous les onglets et à toutes les pages. Ceci est utile pour stocker les préférences de l’utilisateur au niveau de l’application (par exemple, la langue), mais ne doit être utilisé que si la valeur doit être associée à la combinaison utilisateur et navigateur.
Évitez de stocker des secrets ou des données identifiant un patient dans le stockage du navigateur, sauf si une fonctionnalité l’exige explicitement et que le compromis de confidentialité a été examiné.