StatefulWidget vs StatelessWidget.
StatelessWidget -- Un widget qui ne nécessite pas d'état mutable.
-
Un widget sans état est un widget qui décrit une partie de l'interface utilisateur en construisant une constellation d'autres widgets qui décrivent plus concrètement l'interface utilisateur. l'interface utilisateur de manière plus concrète. Le processus de construction se poursuit récursivement jusqu'à ce que la description de l'interface utilisateur soit entièrement entièrement concrète (par exemple, elle est entièrement constituée de RenderObjectWidgets, qui décrivent des RenderObjects concrets).
-
El stateless
est utile lorsque la partie de l'interface utilisateur que vous décrivez ne dépend pas d'autre chose que des informations de configuration de l'objet lui-même et de l'interface utilisateur. que les informations de configuration de l'objet lui-même et le BuildContext dans lequel le widget est gonflé. Pour les compositions qui peuvent changer dynamiquement, par exemple parce qu'elles ont un état interne ou en fonction de l'état du système, envisagez d'utiliser la fonction StatefulWidget
.
class GreenFrog extends StatelessWidget {
const GreenFrog({ Key key }) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(color: const Color(0xFF2DBD3A));
}
}
StatefulWidget -- Un widget qui a un état mutable.
- Les widgets à état sont utiles lorsque la partie de l'interface utilisateur que vous décrivez peut changer de façon dynamique.
Lorsque Flutter construit un StatefulWidget
il crée un objet State. Cet objet est l'endroit où tous les états mutables de ce widget sont conservés.
Le concept d'État est défini par deux choses :
1) Les données utilisées par le widget peuvent changer.
2) Les données ne peuvent pas être lues de manière synchrone lorsque le widget est construit. (Tous les état doit être établi au moment où la méthode de construction est appelée).
Cycle de vie du StatefulWidget
Le cycle de vie comporte les étapes simplifiées suivantes :
-
createState() -- Lorsque Flutter reçoit l'instruction de construire un StatefulWidget, il appelle immédiatement
createState()
.
-
Crée l'état mutable pour ce widget à un emplacement donné dans l'arbre.
-
Les sous-classes doivent surcharger cette méthode pour renvoyer une instance nouvellement créée de leur sous-classe State associée :
@override
_MyState createState() => _MyState();
-
monté == true -- Tous les widgets ont un bool
this.mounted
propriété. Elle devient vraie lorsque le buildContext
est attribué. C'est une erreur d'appeler setState
lorsqu'un widget est démonté. Si cet objet State se trouve actuellement dans un arbre.
-
Après avoir créé un objet State et avant d'appeler initState
le cadre de travail "monte" l'objet State en l'associant à un objet de type
BuildContext
. L'objet State reste monté jusqu'à ce que le cadre
appelle dispose()
après quoi, le cadre ne demandera plus jamais à l'utilisateur d'utiliser l'outil.
Objet d'État à construire à nouveau.
-
C'est une erreur d'appeler setState à moins que monté soit vrai.
bool get mounted => _element != null;
-
initState() -- C'est la première méthode appelée lorsque le widget est créé (après le constructeur de la classe, bien sûr).
initState
est appelé une fois et une seule. Il doit appeler super.initState().
-
Initialiser les données qui reposent sur le BuildContext spécifique de l'instance créée du widget.
-
Initialiser les propriétés qui dépendent du "parent" de ces widgets dans l'arbre.
-
S'abonner aux flux, ChangeNotifiers
ou tout autre objet qui pourrait modifier les données de ce widget.
@override
initState() {
super.initState();
// Add listeners to this class
cartItemStream.listen((data) {
_updateWidget(data);
});
}
-
didChangeDependencies() -- Appelé lorsqu'une dépendance de cet objet State change.
-
Cette méthode est également appelée immédiatement après initState
. Il est prudent d'appeler BuildContext.inheritFromWidgetOfExactType
de cette méthode.
-
Les sous-classes remplacent rarement cette méthode car le framework appelle toujours la méthode build après les changements de dépendances. Certaines sous-classes surchargent cette méthode parce qu'elles ont besoin d'effectuer un travail coûteux (par exemple, le réseau réseau) lorsque leurs dépendances changent et que ce travail serait trop coûteux trop coûteux pour être effectué à chaque build.
@protected
@mustCallSuper
void didChangeDependencies() { }
-
construire() -- Décrit la partie de l'interface utilisateur représentée par le widget.
Le cadre appelle cette méthode dans un certain nombre de situations différentes :
- Après avoir appelé
initState
.
- Après avoir appelé
didUpdateWidget
.
- Après avoir reçu un appel à
setState
.
- Après qu'une dépendance de cet objet d'état change (par exemple, un InheritedWidget référencé par le build précédent change).
- Après avoir appelé la désactivation, puis réinséré l'objet State dans l'arbre à un autre endroit.
-
La structure remplace le sous-arbre situé sous ce widget par le widget renvoyé par cette méthode, soit en mettant à jour le sous-arbre existant, soit en supprimant le sous-arbre et en gonflant un nouveau sous-arbre. existant ou en supprimant le sous-arbre et en gonflant un nouveau sous-arbre, selon que le widget renvoyé par cette méthode peut ou non mettre à jour la racine (Root) du sous-arbre existant. Racine du sous-arbre existant, comme déterminé par l'appel de la méthode Widget.canUpdate
.
-
En général, les implémentations renvoient une constellation de widgets nouvellement créée, configurée avec les informations du constructeur de ce widget. de ce widget, les données BuildContext et l'état interne de cet objet State.
@override
Widget build(BuildContext context, MyButtonState state) {
... () { print("color: $color"); } ...
}
-
didUpdateWidget() -- Appelé à chaque fois que la configuration du widget est modifiée.
-
Si le widget parent est reconstruit et demande que cet emplacement dans l'arborescence soit mis à jour pour afficher un nouveau widget ayant le même type d'exécution et la même clé Widget.key, le framework mettra à jour la propriété widget de cet objet State afin de faire référence au nouveau widget. widget de cet objet State pour faire référence au nouveau widget, puis appelle cette méthode avec le widget précédent comme argument.
-
Remplacez cette méthode pour réagir lorsque le widget change (par exemple, pour lancer des animations implicites).
-
Le framework appelle toujours build après avoir appelé didUpdateWidget, ce qui signifie que tout appel à setState dans didUpdateWidget est redondant.
@mustCallSuper
@protected
void didUpdateWidget(covariant T oldWidget) { }
-
setState() -- Chaque fois que vous modifiez l'état interne d'un objet State, effectuez le changement dans une fonction que vous passez à la fonction
setState
:
-
Appel à setState notifie au cadre que l'état interne de cet objet a changé d'une manière qui pourrait avoir un impact sur l'interface utilisateur. dans ce sous-arbre, ce qui amène le framework à planifier une construction pour les objets suivants
cet objet État.
-
Si vous changez l'état directement sans appeler setState le cadre peut ne pas programmer une construction et l'interface utilisateur de ce sous-arbre peut ne pas être mise à jour pour refléter le nouvel état.
setState(() { _myState = newValue });
-
désactiver() -- Deactivate est appelé lorsque l'État est retiré de l'arbre, mais il peut être réinséré avant la fin du changement de trame en cours. Cette méthode existe essentiellement parce que les objets State peuvent être déplacés d'un point à un autre de l'arbre.
- Le framework appelle cette méthode chaque fois qu'il supprime cet objet State de l'arbre. Dans certains cas, le framework réintroduira l'objet objet State dans une autre partie de l'arbre (par exemple, si le sous-arbre contenant cet objet State est greffé d'un endroit à un autre de l'arbre). à un autre). Si cela se produit, le framework s'assurera qu'il appelle la commande build pour donner à l'objet State une chance de s'adapter à son nouvel emplacement dans l'arbre. Si le framework réintègre ce sous-arbre, il le fera avant la fin de la trame d'animation. avant la fin de la trame d'animation dans laquelle le sous-arbre a été retiré de l'arbre. retiré de l'arbre. Pour cette raison, les objets State peuvent différer la libération de la plupart des ressources jusqu'à ce que le framework appelle leur méthode leur méthode dispose.
Elle est rarement utilisée.
@protected
@mustCallSuper
void deactivate() { }
-
dispose() -- Appelé lorsque cet objet est retiré de l'arbre de façon permanente.
-
Le cadre appelle cette méthode lorsque cet objet State ne sera plus jamais construit. Après que le framework ait appelé dispose()
l'objet State est considéré comme non monté et la propriété mounted est fausse. C'est une erreur d'appeler setState à ce stade. Cette étape du cycle de vie est terminal : il n'y a aucun moyen de remonter un objet State qui a été éliminé. éliminé.
-
Les sous-classes doivent surcharger cette méthode pour libérer toutes les ressources retenues par cet objet (par exemple, arrêter toute animation active).
@protected
@mustCallSuper
void dispose() {
assert(_debugLifecycleState == _StateLifecycle.ready);
assert(() { _debugLifecycleState = _StateLifecycle.defunct; return true; }());
}
Pour plus d'informations, voir aquí aquí , aquí
3 votes
Vous pouvez composer votre mise en page à partir de différents types de widgets, mais cela ne signifie pas que vous héritez des caractéristiques de la composition pour affecter chaque widget. Ce que je veux dire, c'est que vous pouvez avoir un conteneur sans état qui a un enfant d'un autre conteneur qui est déclaré comme StatefulWidget quelque part ailleurs, l'état du conteneur n'affectera que ce seul composant. Il s'agit donc d'avoir une composition de différents types de widgets, chacun fonctionnant comme vous le souhaitez.
3 votes
Pour compliquer encore plus les choses, il existe un troisième type de widget :
InheritedWidget
Ce qui peut faireStatelessWidget
mettre à jour.