Quelle est la bonne façon d'utiliser un InheritedWidget? Jusqu'à présent, j'ai compris que cela vous donne la possibilité de propager des données dans l'arborescence des widgets. À l'extrême, si vous mettez est en tant que RootWidget, il sera accessible à partir de tous les widgets de l'arborescence sur toutes les routes, ce qui est bien parce que d'une manière ou d'une autre, je dois rendre mon ViewModel / Model accessible pour mes widgets sans avoir à recourir aux globaux ou aux singletons.
MAIS InheritedWidget est immuable, alors comment puis-je le mettre à jour? Et plus important encore, comment mes widgets avec état sont-ils déclenchés pour reconstruire leurs sous-arbres?
Malheureusement, la documentation est ici très peu claire et après discussion avec beaucoup de monde, personne ne semble vraiment savoir quelle est la bonne façon de l'utiliser.
J'ajoute une citation de Brian Egan:
Oui, je le vois comme un moyen de propager des données dans l'arborescence. Ce que je trouve déroutant, d'après la documentation de l'API:
"Les widgets hérités, lorsqu'ils sont référencés de cette manière, obligeront le consommateur à se reconstruire lorsque le widget hérité changera d'état."
Quand j'ai lu ceci pour la première fois, j'ai pensé:
Je pourrais insérer des données dans InheritedWidget et les muter plus tard. Lorsque cette mutation se produit, elle reconstruira tous les widgets qui référencent mon InheritedWidget Ce que j'ai trouvé:
Afin de muter l'état d'un InheritedWidget, vous devez l'envelopper dans un StatefulWidget.Vous modifiez ensuite l'état de StatefulWidget et transmettez ces données à InheritedWidget, qui transmet les données à tous ses enfants. Cependant, dans ce cas, il semble reconstruire l'arborescence entière sous le StatefulWidget, pas seulement les widgets qui font référence au InheritedWidget. Est-ce exact? Ou saura-t-il en quelque sorte ignorer les widgets qui font référence à InheritedWidget si updateShouldNotify renvoie false?
la source
MyInherited.of(context)
.updateShouldNotify
test fait toujours référence à la mêmeMyInheritedState
instance, ne revient-il pas toujoursfalse
? Certes, labuild
méthodeMyInheritedState
consiste à créer de nouvelles_MyInherited
instances, mais ledata
champ fait toujours référence àthis
non? J'ai des problèmes ... Fonctionne si je code juste en durtrue
.TL; DR
N'utilisez pas de calculs lourds dans la méthode updateShouldNotify et utilisez const au lieu de new lors de la création d'un widget
Tout d'abord, nous devons comprendre ce qu'est un objet Widget, Element et Render.
Nous sommes maintenant prêts à plonger dans InheritedWidget et la méthode de BuildContext inheritFromWidgetOfExactType .
À titre d'exemple, je recommande de considérer cet exemple de la documentation de Flutter sur InheritedWidget:
InheritedWidget - juste un widget qui implémente dans notre cas une méthode importante - updateShouldNotify . updateShouldNotify - une fonction qui accepte un paramètre oldWidget et renvoie une valeur booléenne: true ou false.
Comme tout widget, InheritedWidget a un objet Element correspondant. Il s'agit de InheritedElement . InheritedElement appelle updateShouldNotify sur le widget chaque fois que nous construisons un nouveau widget (appelez setState sur un ancêtre). Lorsque updateShouldNotify retourne true, InheritedElement itère dans les dépendances (?) Et appelle la méthode didChangeDependencies dessus.
Où InheritedElement obtient les dépendances ? Ici, nous devrions examiner la méthode inheritFromWidgetOfExactType .
inheritFromWidgetOfExactType - Cette méthode définie dans BuildContext et chaque élément implémente l'interface BuildContext (Element == BuildContext). Donc, chaque élément a cette méthode.
Regardons le code de inheritFromWidgetOfExactType:
Ici, nous essayons de trouver un ancêtre dans _inheritedWidgets mappé par type. Si l'ancêtre est trouvé, nous appelons alors inheritFromElement .
Le code pour inheritFromElement :
Nous savons maintenant où InheritedElement obtient ses dépendances.
Regardons maintenant la méthode didChangeDependencies . Chaque élément a cette méthode:
Comme nous pouvons le voir, cette méthode marque simplement un élément comme sale et cet élément doit être reconstruit à l'image suivante. Reconstruire signifie appeler la méthode construite sur l'élément de widget correspondant.
Mais qu'en est-il de "La sous-arborescence entière se reconstruit quand je reconstruis InheritedWidget?". Ici, nous devons nous rappeler que les widgets sont immuables et que si vous créez un nouveau widget, Flutter reconstruira le sous-arbre. Comment pouvons-nous y remédier?
la source
À partir de la documentation :
Comme l'a noté l'OP, une
InheritedWidget
instance ne change pas ... mais elle peut être remplacée par une nouvelle instance au même emplacement dans l'arborescence des widgets. Lorsque cela se produit, il est possible que les widgets enregistrés doivent être reconstruits. LaInheritedWidget.updateShouldNotify
méthode effectue cette détermination. (Voir: docs )Alors, comment une instance pourrait-elle être remplacée? Une
InheritedWidget
instance peut être contenue par aStatefulWidget
, qui peut remplacer une ancienne instance par une nouvelle instance.la source
InheritedWidget gère les données centralisées de l'application et les transmet à l'enfant, comme nous pouvons stocker ici le nombre de cartons comme expliqué ici :
la source