Cycles de vie des Provider
Quand est-ce que mon provider est-il créé et libéré ?
Les états par lesquels tous les différents types de providers peuvent passer sont les mêmes :
- Non initialisé (Uninitialized)
- En vie (Alive)
- En pause (Paused)
- Éliminé/Libéré (Disposed)
Disposed / Uninitialized
Un provider Uninitialized ou Disposed n'occupe pas de mémoire puisque son état n'est pas initialisé. En fait, il s'agit simplement d'une définition de la manière de créer l'état du provider lorsque vous en avez besoin. Il restera dans cet état jusqu'à ce qu'un provider Alive ou un WidgetRef de l'interface utilisateur le lise, le regarde ou l'écoute.
Creating -> Alive
Lorsqu'un provider Uninitialized est lu, écouté ou surveillé, son état est créé.
Pendant la création, la fonction de construction de votre provider sera exécutée.
Tous les providers que vous lisez ou surveillez en utilisant le ref
exposé par le callback seront créés si nécessaire et leur état sera récupéré.
S'il y a des dépendances circulaires pendant ce processus de création, Riverpod lancera une erreur. La meilleure façon de corriger cette erreur est de reconcevoir vos dépendances pour avoir un flux de données uni-directionnel.
L'état du provider est stocké dans un ProviderContainer. Dans une application Flutter, ce conteneur se trouve dans un widget ProviderScope.
Ainsi, même si la définition de la manière de créer l'état (le provider) est globale, l'état est en fait local, et peut être différent dans différentes parties de votre interface utilisateur en utilisant des widgets ProviderScope imbriqués et des surcharges.
Ce système est très similaire au fonctionnement des widgets Flutter. Vous ne payez qu'une seule fois pour la définition, mais vous pouvez réutiliser l'état dans différentes parties de l'arbre selon vos besoins.
Alive
Lorsque votre provider est Alive, les modifications de son état entraînent la reconstruction des providers dépendants et/ou de l'interface utilisateur dépendante.
D'un autre point de vue, en tant que framework réactif, vous pouvez surveiller d'autres providers pour que le provider se recrée lui-même dès que l'une de ses dépendances change.
Si vous avez besoin d'un état à longue durée de vie qui dépend d'un autre état, vous pouvez utiliser la méthode listen de Ref pour vous abonner aux changements d'un autre provider sans provoquer la reconstruction du provider.
Si vous devez utiliser l'état d'un autre provider dans un effet secondaire, vous pouvez utiliser la méthode [read] de Ref pour obtenir l'état actuel d'un autre provider.
En général, lors de la construction d'une classe StateNotifier ou ChangeNotifier, vous devez passer le ref
pour permettre au Notifier d'obtenir la valeur actuelle des dépendances si nécessaire. En utilisant les nouvelles classes Notifier
et AsyncNotifier de Riverpod 2.0, la référence est déjà disponible en tant que membre d'instance de la classe.
Alive -> Paused
Lorsqu'un provider Alive n'est plus écouté par d'autres providers ou par l'interface utilisateur, il passe dans un état Paused. Cela signifie qu'il ne réagira plus aux modifications apportées aux providers qu'il écoute. Il s'agit d'une optimisation, car si vous n'écoutez pas le provider, il n'est pas nécessaire de le maintenir en vie. Chaque provider qui n'est pas utilisé sera remis dans un état Paused, ce qui réduit la charge de calcul de votre application.
Si vous devez maintenir un provider en vie pour des effets secondaires, assurez-vous de l'écouter à un endroit approprié de l'interface utilisateur où il doit être maintenu en vie.
Si vous devez effectuer une action lorsqu'un provider est en pause, utilisez la méthode onCancel de la référence pour enregistrer des rappels.
Si vous devez effectuer une action lorsqu'un provider reprend l'état Alive à partir d'un état de pause, utilisez la méthode onResume de la référence pour enregistrer les rappels.
Si vous souhaitez que l'état soit éliminé, de sorte qu'en plus de ne nécessiter aucune ressource de calcul, il soit également libéré de la mémoire de l'état, utilisez le modifieur .autoDispose
dans la définition de votre provider.
Cela lui permettra de passer à l'état Disposed au lieu de Paused lorsqu'il ne sera plus utilisé.
Alive -> Disposing
Il y a plusieurs raisons pour qu'un provider soit libéré.
- Lorsqu'il est défini à l'aide du modifieur
.autoDispose
et qu'il n'est plus surveillé par l'interface utilisateur ou par un autre prestataire - Lorsque le provider est rafraîchi ou invalidé manuellement.
- Lorsque le provider est recréé suite à la modification d'une de ses dépendances surveillées.
L'actualisation fait en sorte que le provider repasse immédiatement par le processus de création, tandis que l'invalidation fait en sorte que la prochaine lecture/veille (read/watch) du provider entraîne la reconstruction de ce dernier.
Exécution d'actions avant la destruction de l'état
Si vous devez effectuer une action quelconque lorsqu'un provider est détruit, utilisez la méthode onDispose de l'objet pour enregistrer des rappels.
L'exemple suivant utilise onDispose pour fermer un StreamController :
final example = StreamProvider.autoDispose((ref) {
final streamController = StreamController<int>();
ref.onDispose(() {
// Ferme le StreamController lorsque l'état de ce provider est détruit.
streamController.close();
});
return streamController.stream;
});
Selon le provider utilisé, il peut déjà s'occuper du processus de nettoyage.
Par exemple, StateNotifierProvider appellera la méthode dispose
du StateNotifier renvoyé.