136 votes

Quelles sont les clés de la classe Stateless widgets ?

Dans la documentation de Flutter, il y a un exemple de code pour une sous-classe de widget sans état, comme indiqué :

class GreenFrog extends StatelessWidget {
  const GreenFrog({ Key key }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return new Container(color: const Color(0xFF2DBD3A));
  }
}

et ceci

class Frog extends StatelessWidget {
  const Frog({
    Key key,
    this.color: const Color(0xFF2DBD3A),
    this.child,
  }) : super(key: key);

  final Color color;

  final Widget child;

  @override
  Widget build(BuildContext context) {
    return new Container(color: color, child: child);
  }
}

Qu'est-ce qu'une clé et quand faut-il utiliser ce super constructeur ? Il semble que si vous avez votre propre constructeur, vous devez avoir {Key key} pourquoi ? J'ai vu d'autres exemples où le mot-clé super est pas utilisé donc c'est là que se situe ma confusion.

0 votes

À certains égards, le concept est similaire à la clé dans React stackoverflow.com/questions/28329382/

1 votes

Ce gars pourrait utiliser des clés pour améliorer ses performances.... vaut la peine d'y jeter un coup d'oeil medium.com/flutter-community/

181voto

Rémi Rousselet Points 45139

TLDR : Tous les widgets devraient avoir un Key key comme en option ou leur constructeur. Key est utilisé par le moteur de flutter à l'étape de la reconnaissance du widget modifié dans une liste.


Il est utile lorsque vous avez un liste ( Column , Row ou autre) de widgets du même type qui peuvent potentiellement être retirés/insérés.

Disons que vous avez ceci (le code ne fonctionne pas, mais vous comprenez l'idée) :

AnimatedList(
  children: [
    Card(child: Text("foo")),
    Card(child: Text("bar")),
    Card(child: Text("42")),
  ]
)

Vous pouvez potentiellement supprimer n'importe lequel de ces widgets individuellement par un simple glissement.

Le problème est que notre liste a une animation lorsqu'un enfant est retiré. Donc, enlevons "bar".

AnimatedList(
  children: [
    Card(child: Text("foo")),
    Card(child: Text("42")),
  ]
)

Le problème : sans Key flutter ne sera pas en mesure de savoir si le deuxième élément de votre Row disparu. Ou si c'est le dernier qui a disparu et que le second voit son enfant changer.

Donc sans Key vous pouvez potentiellement avoir un bug où votre quitter sera jouée sur le dernier élément à la place !


C'est là que Key a lieu.

Si nous reprenons notre exemple, en utilisant la clé, nous aurions ceci :

AnimatedList(
  children: [
    Card(key: ObjectKey("foo"), child: Text("foo")),
    Card(key: ObjectKey("bar"), child: Text("bar")),
    Card(key: ObjectKey("42"), child: Text("42")),
  ]
)

remarquez comment la clé est pas l'indice de l'enfant mais quelque chose d'unique à l'élément.

A partir de ce point, si on enlève encore "bar", on aura

AnimatedList(
  children: [
    Card(key: ObjectKey("foo"), child: Text("foo")),
    Card(key: ObjectKey("42"), child: Text("42")),
  ]
)

Merci à key étant présent, le moteur de flutter sait maintenant avec certitude quel widget a été supprimé. Et maintenant notre quitter L'animation sera jouée correctement sur "bar" au lieu de "42".

3 votes

Je commence à comprendre ce que vous dites. Je suis également novice en matière de développement mobile, alors soyez indulgent avec moi. Pour clarifier votre explication, il n'y a aucun moyen de distinguer les éléments de la carte, même s'ils ont un texte différent comme enfant ? Pour résoudre ce problème, une clé est utilisée comme identifiant unique pour chaque élément. Est-ce correct ?

3 votes

Exactement. Pour différencier les widgets, par défaut, Clutter utilise leur type et leur index dans la liste, à moins que vous ne spécifiiez une clé.

1 votes

C'est plus logique, j'ai une autre question que j'ai mise à jour en tant que Question 2 dans mon message original. Cela semble plus dartlang, pouvez-vous essayer d'expliquer cela ?

55voto

Suragch Points 197

Que sont les clés ?

Les clés sont des identifiants pour les widgets. Tous les widgets en possèdent, pas seulement les StatelessWidgets. Elles sont utilisées par l'arbre des éléments pour déterminer si un widget peut être réutilisé ou s'il doit être reconstruit. Si aucune clé n'est spécifiée (le cas habituel), le type de widget est utilisé pour le déterminer.

Pourquoi utiliser les Clés ?

Les touches sont utiles pour maintenir l'état lorsque le nombre ou la position des widgets change. S'il n'y a pas de clé, le framework Flutter peut ne pas savoir quel widget a changé.

Quand utiliser les clés ?

Ne les utilisez que lorsque le framework a besoin de votre aide pour savoir quel widget mettre à jour.

La plupart du temps, vous n'avez pas besoin d'utiliser des clés. Étant donné que les clés ne sont utiles que pour maintenir l'état, si vous avez un widget sans état dont les enfants sont tous sans état, il n'est pas nécessaire d'utiliser une clé sur celui-ci. Dans ce cas, l'utilisation d'une clé ne fera pas de mal, mais elle ne sera pas non plus utile.

Il y a quelques micro-optimisations que vous pouvez faire en utilisant des clés. Voir cet article .

Où utiliser les clés ?

Placez la clé dans la partie de l'arbre des widgets où le réordonnancement ou l'ajout/suppression a lieu. Par exemple, si vous réordonnez les éléments d'une ListView dont les enfants sont des widgets ListTile, ajoutez les clés aux widgets ListTile.

Quel type de clés utiliser ?

Une clé est simplement un identifiant, mais le type d'identifiant que vous pouvez utiliser peut varier.

Clé de valeur

Une ValueKey est une clé locale qui prend une valeur simple comme une chaîne ou un nombre entier.

Clé d'objet

Si votre widget affiche des données plus complexes qu'une simple valeur, vous pouvez utiliser un ObjectKey pour ce widget.

Clé unique

Ce type de clé vous garantit un identifiant unique à chaque fois. Si vous l'utilisez, cependant, ne la mettez PAS dans le fichier build méthode. Sinon, votre widget n'aura jamais le même ID et l'arbre des éléments ne trouvera jamais de correspondance à réutiliser.

GlobalKey

Les GlobalKeys peuvent être utilisées pour maintenir l'état de votre application, mais utilisez-les avec parcimonie car elles sont similaires aux variables globales. Il est souvent préférable d'utiliser une solution de gestion d'état à la place.

Exemples d'utilisation des clés

Références

12voto

La clé est un objet qui est utilisé pour identifier un widget de façon unique.

Ils sont utilisés pour accéder à l'état ou le restaurer. StatefulWidget (La plupart du temps, nous n'en avons pas besoin du tout si notre arborescence de widgets est composée uniquement de widgets apatrides). Il existe différents types de clés que je vais essayer d'expliquer sur la base de leur utilisation.

Objectif ( key types )

1. Mutation de la collection i.e. remove / add / reorder item to list dans un widget à état, comme une liste de tâches glissante, où les éléments cochés sont supprimés.

ObjectKey, ValueKey & UniqueKey

2. Déplacer le widget d'un Parent à un autre en conservant son état.

GlobalKey

3. Afficher le même widget sur plusieurs écrans et conserver son état.

GlobalKey

4. Valider le formulaire.

GlobalKey

5. Vous voulez donner une clé sans utiliser de données.

UniqueKey

6. Si vous pouvez utiliser un certain champ de données comme l'UUID des utilisateurs comme clé unique.

ValueKey

7. Si vous n'avez pas de champ unique à utiliser comme clé mais que l'objet lui-même est unique.

ObjectKey

8. Si vous avez plusieurs formulaires ou plusieurs widgets du même type qui ont besoin de GlobalKey.

GlobalObjectKey, LabeledGlobalKey whichever is appropriate, similar logic to ValueKey and ObjectKey

N'utilisez pas le hasard string/number comme clé, cela va à l'encontre de l'objectif des clés.

4voto

d0xzen Points 99

La clé est un paramètre facultatif nécessaire pour préserver l'état de votre arbre de widgets, vous devez les utiliser si vous voulez déplacer une collection d'éléments dans votre arbre et préserver l'état de ceux-ci.

La meilleure explication se trouve dans cette vidéo de Google. Quand utiliser les touches - Flutter Widgets 101 Ep. 4

1voto

Azamat Ali Points 11

Avec Dart 2.12 ou supérieur, ajoutez ? après la touche pour la rendre facultative si vous le souhaitez.

class Frog extends StatelessWidget {
  const Frog({
    Key? key,
    this.color: const Color(0xFF2DBD3A),
    this.child,
  }) : super(key: key);

  final Color color;

  final Widget child;

  @override
  Widget build(BuildContext context) {
    return new Container(color: color, child: child);
  }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X