Flutter: Crochets de widgets

Créé le 12 déc. 2018  ·  100Commentaires  ·  Source: flutter/flutter

L'équipe React a récemment annoncé des crochets : https://medium.com/@dan_abramov/making -sense-of-react-hooks-fdbde8803889. En raison de la similitude de Flutter avec React, il serait probablement intéressant de voir si cela convient également à Flutter.

La définition:

Les crochets sont très similaires aux State de StatefulWidget avec une différence principale : nous pouvons avoir autant de crochets que nous le souhaitons sur un widget.
Les crochets ont accès à tous les cycles de vie d'un State (ou d'une version modifiée).

Les crochets peuvent être utilisés sur n'importe quel widget donné. Contrairement à State qui ne peut être utilisé que pour un type de widget spécifique.

Les crochets sont différents des super mixins car ils ne peuvent pas générer de conflits. Les crochets sont _entièrement_ indépendants et sans rapport avec le widget.
Cela signifie qu'un crochet peut être utilisé pour stocker des valeurs et les exposer publiquement sans crainte de conflits. Cela signifie également que nous pouvons réutiliser plusieurs fois le même Hook, contrairement aux mixins.

Le principe:

Les crochets sont essentiellement stockés dans les Element d'un tableau. Ils ne sont accessibles qu'à partir de la méthode build d'un widget. Et les crochets doivent être accessibles sans condition, par exemple :

FAIRE:

Widget build(BuildContext context) {
  Hook.use(MyHook());
}

A NE PAS FAIRE :

Widget build(BuildContext context) {
  if (condition) {
    Hook.use(MyHook());
  }
}

Cette restriction peut sembler très restrictive, mais c'est parce que les crochets sont stockés par leur index. Ni leur type ni leur nom.
Cela permet de réutiliser le même crochet autant de fois que souhaité, sans aucune collision.

Le cas d'utilisation

La partie la plus utile des Hooks est qu'ils permettent d'extraire la logique du cycle de vie dans un composant réutilisable.

Un problème typique avec les widgets Flutter est les objets jetables tels que AnimationController .
Ils nécessitent généralement à la fois un remplacement de initState et de dispose . Mais en même temps ne peut pas être extrait dans un mixin pour des raisons de maintenabilité.

Cela conduit à un code-snipper commun : stanim

class Example extends StatefulWidget {
  <strong i="7">@override</strong>
  ExampleState createState() => ExampleState();
}

class ExampleState extends State<Example>
    with SingleTickerProviderStateMixin {
  AnimationController _controller;

  <strong i="8">@override</strong>
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this, duration: const Duration(seconds: 1));
  }

  <strong i="9">@override</strong>
  void dispose() {
    super.dispose();
    _controller.dispose();
  }

  <strong i="10">@override</strong>
  Widget build(BuildContext context) {
    return Container(

    );
  }
}

Hooks résout ce problème en extrayant la logique du cycle de vie. Cela conduit à un code potentiellement _beaucoup_ plus petit :

class Example extends StatelessWidget {
  <strong i="15">@override</strong>
  Widget build(BuildContext context) {
    AnimationController controller = useAnimationController(duration: const Duration(seconds: 1));
    return Container(

    );
  }
}

Une implémentation naïve d'un tel crochet pourrait être la fonction suivante :

AnimationController useAnimationController({Duration duration}) {
  // use another hook to obtain a TickerProvider
  final tickerProvider = useTickerProvider();

  // create an AnimationController once
  final animationController = useMemoized<AnimationController>(
    () => AnimationController(vsync: tickerProvider, duration: duration)
  );
  // register `dispose` method to be closed on widget removal
  useEffect(() => animationController.dispose, [animationController]), 

   // synchronize the arguments
  useValueChanged(duration, (_, __) {
    animationController.duration = duration;
  });

  return animationController;
}

useAnimationController est l'un de ces "Hook".

Où une implémentation naïve d'un tel crochet serait la suivante :

Ce code devrait ressembler à quelqu'un habitué à la classe State . Mais cela a quelques points intéressants :

  • Le crochet prend entièrement en charge le AnimationController , de sa création à sa suppression. Mais aussi des mises à jour.
  • Il peut facilement être extrait dans un emballage réutilisable
  • Il prend également en charge la mise à jour de duration lors du rechargement à chaud au lieu de créer un AnimationController dans le initState .
  • Les crochets peuvent utiliser d'autres crochets pour construire une logique plus complexe

Désavantages

Les crochets ont un coût. L'accès à une valeur a un surcoût similaire à un InheritedElement . Et ils nécessitent également de créer un nouvel ensemble d'objets éphémères tels que des fermetures ou des "Widget" similaires.

Je n'ai pas encore exécuté de benchmark pour voir la vraie différence cependant


Un autre problème concerne le rechargement à chaud.

Ajout de crochets à la fin de la liste si c'est bien. Mais comme les crochets fonctionnent en fonction de leur ordre, l'ajout de crochets au milieu de crochets existants entraînera une réinitialisation partielle de l'état. Exemple:

Passer de A, B à A, C, B réinitialisera l'état de B (en appelant à nouveau dispose et initHook ).

Conclusion

Hooks simplifie _beaucoup_ le monde des widgets en permettant une plus grande réutilisation du code. Surtout sur les scénarios très courants tels que disposer, mémoriser et regarder une valeur.

Ils peuvent être utilisés pour remplacer entièrement un StatefulWidget.

Mais ils nécessitent cependant un changement d'état d'esprit, et la réinitialisation partielle de l'état lors de la refactorisation peut être gênante.

Il est possible d'extraire des crochets en dehors de Flutter en créant des éléments personnalisés. Il n'est pas nécessaire de modifier les sources pour l'instant.

Mais en raison de la spécificité des crochets, il bénéficierait _beaucoup_ d'un linter personnalisé. Quels packages externes ne peuvent pas fournir pour le moment.

Prime

~Une implémentation en cours de développement est disponible ici : https://github.com/rrousselGit/flutter_hooks (les dernières fonctionnalités sont sur la branche prod-ready ).~

~Une version est prévue prochainement en alpha. Mais la mise en œuvre actuelle fonctionne dans une certaine mesure.~

Disponible ici https://pub.dartlang.org/packages/flutter_hooks# -readme-tab-

framework new feature

Commentaire le plus utile

Je voulais juste dire - si quelqu'un de l'équipe Flutter souhaite discuter 1: 1 de Hooks, je serais heureux d'expliquer le contexte historique et technique derrière pourquoi nous les adoptons dans React. Ce commentaire pourrait également être intéressant : https://github.com/reactjs/rfcs/pull/68#issuecomment -439314884.

Tous les 100 commentaires

@Hixie @eseidelGoogle

Voici un suivi de https://twitter.com/ericmander/status/1070024779015479302 avec quelques détails sur ce que j'avais en tête. Juste au cas où l'équipe Flutter voudrait investir davantage sur le sujet

Salut @rrousselGit Je regardais votre paquet flutter_hooks l'autre jour. Je ne sais pas quelles options nous avons pour les implémenter dans Flutter, mais j'ai remarqué que vous transmettez des méthodes de hook via HookContext, alors que dans React, les hooks peuvent être créés séparément et utilisés comme une sorte de "mixin d'état". La principale différence est que flutter_hooks semble exiger que toutes les méthodes de hook soient intégrées au package, tandis que React permet aux méthodes de hook d'être totalement séparées.

Il semblerait que cela soit essentiel pour correspondre à la spécification React. Avez-vous des idées sur la façon dont cela pourrait être réalisé?

MODIFIER :

HookContext a été supprimé et tous les hooks sont désormais des méthodes statiques. Donc, ce qui suit est maintenant obsolète


Mon package le fait à des fins de complétion automatique, mais ce n'est pas une nécessité.

À la place de

context.useSomeHook()

Nous pouvons avoir

useSomeHook(context)

Cela ne change strictement rien à part la découvrabilité.

La caractéristique clé est

T HookContext.use<T>(Hook);

Ce qui vous permet de construire vos propres crochets à partir de là. Tant que nous avons cette méthode, nous pouvons faire tout ce que fait React.

Mais en raison de la spécificité des crochets, il bénéficierait beaucoup d'un linter personnalisé. Quels packages externes ne peuvent pas fournir pour le moment.

Je vous recommande de voter pour (et d'ajouter votre cas d'utilisation à)
https://github.com/dart-lang/linter/issues/697. Ce serait formidable si les paquets pouvaient fournir leurs propres peluches personnalisées.

Un autre problème concerne le rechargement à chaud.

Celui-ci m'inquiète. Il serait dommage que nous dégradions l'expérience de rechargement à chaud.

Disponible ici https://pub.dartlang.org/packages/flutter_hooks

Pouvez-vous expliquer quels sont les avantages de l'intégration de cela dans le framework Flutter par rapport au simple fait d'avoir un package externe ?

À propos du rechargement à chaud, je l'ai intégré et il est facile à utiliser.

Le seul vrai problème est # 26503, qui semble nécessiter une modification de l'outillage pour être résolu. Et je n'ai pas la bande passante pour le faire.


Il y a plusieurs petites améliorations que nous pouvons apporter aux hooks en les intégrant dans Flutter :

  • Une certaine augmentation des performances, en ne dépendant pas de StatefulElement
  • Refactoring/analyse, ce qui n'est actuellement pas possible ou très limité en utilisant analyzer_plugin

Mais je pense que la principale raison est la suivante : les crochets font partie d'un travail à plus grande échelle sur React, c'est-à-dire le rendu asynchrone.

Si Flutter veut un jour suivre la route du rendu asynchrone (et il le devrait), cela nécessitera deux choses :

  • Changements de cadre multiples
  • Quelque chose de similaire aux crochets

Il y a aussi l'aspect communautaire évident. Avec 270 étoiles en un mois et une place sur https://github.com/trending/dart?since=monthly sans que je les ai vraiment annoncées, les crochets sont définitivement quelque chose qui suscite l'intérêt de la communauté.

L'objectif des hooks est de modifier la syntaxe des widgets afin que les utilisateurs puissent partager une logique spécifique au cycle de vie avec pub.

Les crochets étant officiellement pris en charge, cela augmenterait de manière exponentielle l'effort de la communauté.

Curieux : Pourriez-vous expliquer comment vous l'avez fait fonctionner pour le rechargement à chaud ?

J'ai étendu StatefulElement au lieu de ComponentElement, afin que je puisse avoir accès à reassemble .
Cela permet au prochain appel build de modifier la liste de crochets tout en empêchant la reconstruction normale de le faire.

Fondamentalement, si previousHook.runtimeType != newHook.runtimeType à un index donné, ce crochet et tous les suivants seront éliminés.

La partie "tout ce qui suit" est due au fait qu'un crochet peut utiliser d'autres crochets ; il ne suffit donc pas d'en supprimer un.
Après un mois d'utilisation constante, c'est rarement un problème.

C'est en fait le contraire, l'expérience de rechargement à chaud semble améliorée. Comme tout se trouve dans la méthode build , un rechargement à chaud applique toujours les modifications (par opposition à un initState ). Un exemple typique est AnimationController :

final animationController = useAnimationController(duration: const Duration(second: 1));

Ce crochet permet un rechargement à chaud en douceur de la durée; ce qui nécessite généralement un redémarrage à chaud.

J'ai commencé à traduire une partie de mon application principale pour supprimer certains passe-partout. Je ne vois pas les crochets comme une fonctionnalité mais comme un modèle complet. Il s'agit de nombreux sujets qui ne demandent qu'à être mis en œuvre et qui bénéficieraient grandement à la productivité mais aussi à la maintenance. J'ai commencé avec l'animation, en supprimant les contrôleurs et j'aimerais voir Hooks for Firebase ou d'autres cas courants.

C'est en fait le contraire, l'expérience de rechargement à chaud semble améliorée. Comme tout se trouve dans la méthode de construction, un rechargement à chaud applique toujours les modifications (par opposition à un initState).

👍 J'ai également réalisé cette réalisation quelques semaines après avoir vu la proposition de Sebastian pour la première fois.

La partie "tout ce qui suit" est due au fait qu'un crochet peut utiliser d'autres crochets ; il ne suffit donc pas d'en supprimer un.

J'ai aussi pensé qu'en JS, une heuristique pourrait peut-être être utile : si le rechargement à chaud provoque la levée render ( build de Flutter) (par exemple, en raison de types incompatibles), nous réinitialisons tous les états des crochets et réessayons. Si cela échoue à nouveau, nous échouons.

Je suppose que vous n'avez pas ce problème en raison de la frappe forte? Je ne suis pas sûr. Que se passe-t-il si vous commencez à éditer avec un crochet d'état de chaîne, puis modifiez le code pour supposer qu'il s'agit d'un nombre ?

Que se passe-t-il si vous commencez à éditer avec un crochet d'état de chaîne, puis modifiez le code pour supposer qu'il s'agit d'un nombre ?

Tu veux dire partir de :

final counter = useState(0)

à:

final name = useState('foo');

?

Si c'est le cas, le système de typage détecte correctement que le type a changé. C'est parce que le type useState est en fait useState<int> vs useState<String> .

JS aura probablement plus de mal ici.

Je ne comprends pas vraiment ce que cela vous sauve. Une déclaration facile à comprendre, une ligne facile à comprendre dans l'initState et une ligne facile à comprendre dans le dispose, sont remplacées par une ligne moins efficace et complètement opaque dans la méthode de construction (où la performance est critique). Cela ne semble pas être une bonne affaire. Pourriez-vous détailler les avantages ici ?

(Cela dit, https://pub.dartlang.org/packages/flutter_hooks semble déjà implémenter tout ici, donc je suppose que nous n'avons rien besoin d'ajouter à la plate-forme ?)

Les crochets sont une solution à un problème auquel React est confronté depuis des années. Et comme Flutter s'inspire beaucoup de React, il a également importé ces problèmes.

Je suis assez mauvais en marketing, donc je suggérerais fortement de regarder l'équipe React en parler. Leur introduction commence ici https://youtu.be/dpw9EHDh2bM.

Suivi d'une comparaison côte à côte avant/après de Dan Abramov (qui a répondu ici à quelques commentaires ci-dessus).

Le fait est que tout ce qu'ils restent dans cette conversation s'applique également à Flutter (y compris leur blog sur les mixins nuisibles https://reactjs.org/blog/2016/07/13/mixins-considered-harmful.html)


Cela dit, les crochets peuvent être résumés dans la phrase accrocheuse suivante :

Avec les hooks, vous pouvez "pub get" un pourcentage encore plus important de votre candidature

En effet, les crochets peuvent être entièrement extraits du widget et publiés sur pub pour que d'autres puissent les utiliser. C'est actuellement quelque chose d'impossible avec StatefulWidget car notre logique est liée aux cycles de vie de State .

Un autre effet des crochets est qu'ils modifient la façon dont le code est regroupé. Nous avons actuellement les éléments suivants :

initState() {
  a = A(widget.foo);
  b = B(widget.bar);
}

didUpdateWidget(SomeWidget old) {
  if (old.foo != widget.foo) {
    a.foo = widget.foo;
  }
  if (old.bar != widget.bar) {
    b.bar = widget.bar;
  }
}

dispose() {
  a.dispose();
  b.dispose();
}

Tout est mélangé et réparti sur plusieurs cycles de vie. Il devient très difficile de voir si on a oublié de supprimer/mettre à jour une variable.

Avec les crochets, cela devient le suivant :

final a = useMemoized(() => A(foo));
useValueChanged(foo, () => a.foo = foo});
useEffect(() => a.dispose, [a]);

final b = useMemoized(() => B(bar));
useValueChanged(bar, () => b.bar = bar});
useEffect(() => b.dispose, [b]);

Tout est désormais regroupé. Cela devient beaucoup plus évident si nous avons oublié de supprimer/mettre à jour une variable ou non, et nous pouvons facilement extraire cette logique dans une fonction statique qui fait tout en interne.

Les crochets sont conformes à DRY. Nous écrivons une fois la logique pour créer/mettre à jour/supprimer une variable. Et nous le réutilisons partout au lieu de le copier-coller.

Un exemple visuel (en React):


Dans l'ensemble, bien qu'il soit incroyable qu'il soit possible d'implémenter des crochets en dehors du référentiel Flutter ; Je ne pense pas que ça doive rester comme ça.

C'est comme si Flutter ne fournissait que la classe de base Widget et faisait StatefulWidget une dépendance externe : cela n'a aucun sens.

Flutter est un framework, nous ne voulons pas proposer que les bases

Ce qui signifie que nous voudrons également :

  • fournir des crochets pour tous les aspects du cadre qui en bénéficieraient
  • interagir avec l'inspecteur de widgets (l'interface utilisateur actuelle n'est pas optimisée pour un tel cas d'utilisation)
  • refactoring/linter
  • fournir un utilitaire de test

Celles-ci nécessitent une énorme quantité de travail et peuvent nécessiter plusieurs relations publiques dans Flutter.
C'est très loin du cadre d'un petit forfait entretenu par un seul gars sur son temps libre.

Les hooks sont DRY et sont des mixins de logique métier/état qui favorisent une colocation propre du code. L'alternative est la répétition fragmentée dans une base de code.

Bien que je convienne que sur le papier, il est plus opaque, le motif est reproductible et compréhensible, donc après une journée d'utilisation, il devient transparent. C'est comme n'importe quel autre modèle de programmation : opaque lorsque vous démarrez, transparent lorsque vous l'utilisez, mais avec Hooks, la transition est presque instantanée.

En réaction, de nombreux développeurs pensent que les hooks rendent inutiles de nombreux cas qui reposaient à l'origine sur des composants de classe. Par conséquent, le composant fonctionnel viendrait au centre de la scène dans un avenir proche.

Ma question naïve est de savoir si la prise en charge d'un widget fonctionnel dans Flutter a également un sens. Je comprends que le widget actuellement fonctionnel n'est pas recommandé en raison de l'absence de lien vers son propre élément et de l'absence de son propre BuildContext. Serait-il avantageux d'introduire un nouveau mécanisme fonctionnel capable de créer les mêmes objets sous-jacents que le widget de classe?

@ivenxu C'est aussi quelque chose que j'ai créé, dans un autre package : https://github.com/rrousselGit/functional_widget

C'est un générateur de code qui génère une classe à partir d'une fonction (avec des clés et tout) et est compatible avec les crochets pour générer un HookWidget

La somme des deux est :

<strong i="11">@hwidget</strong>
Widget foo(BuildContext context, {Duration duration}) {
  final controller = useAninationController(duration: duration);
  useEffect(controller.forward, [controller]);

  final value = useAnination(controller);
  return Text(value.toString());
}

Cela fait un joli texte qui passe progressivement de 0 à 1.
En 6 lignes de code...
Ce qui nécessiterait plus de 30 lignes avec les widgets habituels.

Et je ne compte pas les remplacements debugFillProperties et operator== générés automatiquement.

@rrousselGit J'étais au courant de ton travail de widget fonctionnel, bravo et merci ! Cependant, je parle du support natif de flutter.

Au fait, comment le débogage attaché se passe-t-il pour le code-gen ? Est-ce possible de définir un point d'arrêt dans foo() et d'examiner la variable locale ? À quoi ressemble la pile d'appels ?

Parfois, le paradigme fonctionnel pour le composant/widget est beaucoup plus concis que son homologue de classe. Je cherche donc des idées pour savoir si un widget fonctionnel pris en charge en natif ferait une différence.

Avec les crochets, cela devient le suivant

Je pense vraiment que l'image "avant" ici est beaucoup plus claire et plus facile à comprendre que l'image "après". Évidemment, c'est un avis subjectif.

C'est comme si Flutter ne fournissait que la classe de base Widget et faisait de StatefulWidget une dépendance externe : cela n'a aucun sens.

Faire cela serait en fait tout à fait conforme à la philosophie de superposition de Flutter. La principale raison pour laquelle nous avons StatefulWidget comme partie centrale de première classe de la couche de widgets dans le framework est que d'autres fonctionnalités du framework en dépendent (par exemple GlobalKey ), donc nous ne pouvons pas. Mais autant que possible, nous aimons extraire les fonctionnalités afin qu'elles ne soient pas dans le noyau.

Je pense qu'il est très logique d'avoir cela comme un package pour ceux qui veulent l'utiliser. S'il y a quelque chose que nous pouvons faire dans le cadre de base pour rendre sa mise en œuvre meilleure, plus efficace, etc., alors nous devrions certainement le faire.

Je pense que c'est un super projet, et je suis le dossier avec intérêt.

Cela dit, je ne vois pas très bien pourquoi cela devrait figurer dans le cadre. Cela semble être un modèle très utile que certaines personnes aimeront et que d'autres préféreront ne pas utiliser.

@rrousselGit Je soupçonne que vous auriez beaucoup de succès en continuant à développer cela en tant que package séparé et en ouvrant des problèmes / PR pour le cadre de base qui aiderait à le faire réussir davantage. S'il y a quelque chose que vous avez besoin d'exposer dans le cadre qui n'est pas actuellement pour que cela fonctionne, abordons-le. S'il y a un bogue dans le framework qui l'empêche de fonctionner, faisons en sorte que cela fonctionne !

Et FWIW, je dis cela après avoir eu une expérience similaire avec flutter_svg - qui a conduit à quelques contributions au framework et a pu être utile à de nombreuses personnes en tant que package.

Je viens de comprendre :
Si les crochets sont implémentés dans Flutter, un bon candidat est ComponentElement.

Cela signifie qu'au lieu d'avoir un nouveau type de Widget, cela rendrait à la fois StatelessWidget et StatefulWidget compatibles avec les crochets.

Cette approche pourrait permettre aux deux syntaxes de coexister. Cela pourrait être utile étant donné que les deux syntaxes ont leurs avantages et leurs inconvénients


Je suis d'accord avec les crochets en dehors de Flutter pour l'instant.

Ma seule préoccupation est qu'en étant non officiel, cela réduira l'utilisation globale des crochets. Et donc de réduire le nombre d'hameçons disponibles sur pub.

Considérant que le plus grand avantage des crochets est l'impact sur la communauté (crochets personnalisés publiables sur pub), cela nuit à leur utilité.

Je voulais juste dire - si quelqu'un de l'équipe Flutter souhaite discuter 1: 1 de Hooks, je serais heureux d'expliquer le contexte historique et technique derrière pourquoi nous les adoptons dans React. Ce commentaire pourrait également être intéressant : https://github.com/reactjs/rfcs/pull/68#issuecomment -439314884.

@Hixie ou @dnfield est-ce que quelqu'un d'entre vous a déjà contacté @gaearon ?

En tant qu'utilisateur de Flutter qui utilise également beaucoup React, je peux dire que les crochets ont vraiment changé la donne pour React. J'écris tout mon nouveau code en utilisant exclusivement des hooks et je porte toutes les anciennes classes vers des hooks au fur et à mesure que je travaille dessus. Les avantages d'avoir tout le code lié à une partie spécifique de votre composant au même endroit sont incroyables !

Je pense que ce serait génial s'il y avait un effort pour évaluer si ce paradigme cadrerait ou non avec Flutter ❤️

J'avais raté ce commentaire ! Je viens de les contacter.

Je dois admettre que je ne comprends pas vraiment comment Hooks s'applique à Flutter. Il existe déjà des packages Hooks si vous souhaitez les expérimenter (certains sont mentionnés dans ce bogue ci-dessus). Au fond, je ne comprends pas trop à quel problème le concept résout.

Pour plus de détails sur mon point de vue ici, voir mes commentaires précédents : https://github.com/flutter/flutter/issues/25280#issuecomment -455846788, https://github.com/flutter/flutter/issues/25280#issuecomment - 455847134, https://github.com/flutter/flutter/issues/25280#issuecomment -456272076.

Au fond, je ne comprends pas trop à quel problème le concept résout.

Les crochets sont comme des mixins d'état, mais sans les problèmes inhérents aux mixins : pas de conflit de variable et peuvent être utilisés plus d'une fois.

Les crochets peuvent résoudre l'un des plus gros problèmes que Flutter rencontre actuellement avec les widgets avec état : gérer tous ces contrôleurs.

Chaque contrôleur a besoin à la fois d'un initState, didUpdateWidget et dispose, qui sont _toujours_ implémentés de la même manière.

Nous ne pouvons pas l'extraire dans une classe/mixin de base car nous en aurons peut-être besoin de plusieurs.
Donc, à la place, nous devons copier-coller la logique partout.
Mais ce n'est pas très bon non plus. Il est facile d'oublier une étape, comme remplacer dispose .


Le vrai problème avec les crochets est qu'ils nécessitent beaucoup de travail pour être implémentés.

Le cadre de base est simple. Mais en raison de leur comportement unique, ils nécessitent une intégration profonde avec les outils de linter et de refactoring.

Et pour une implémentation optimale, certaines fonctionnalités de langages comme tupple/déstructuration peuvent être nécessaires.

Je ne pense pas que cela réponde vraiment aux commentaires que j'avais ci-dessus (https://github.com/flutter/flutter/issues/25280#issuecomment-455846788 et https://github.com/flutter/flutter/issues/25280# issuecomment-456272076 notamment).

Hum, @gaearon l'expliquera probablement mieux que moi, mais de mon point de vue :

  • L'argument de lisibilité dépend de la taille du widget. Sur les widgets plus grands, les crochets ont tendance à être en fait _plus_ lisibles car tous les bits associés sont ensemble au lieu d'être répartis sur les cycles de vie.

  • moins de bugs. Leur API déclarative rend plus difficile d'oublier de mettre à jour/nettoyer un état.

  • à propos du "pourquoi devraient-ils être centraux ?", j'aime la métaphore utilisée par Dan Abramov.
    Les crochets sont aux widgets ce que les électrons sont aux atomes.
    Cela n'a pas de sens de les exclure, quand ce sont des primitifs utilisés pour construire de plus grandes choses.
    Il ne s'agit pas seulement d'implémenter des crochets. L'ensemble du cadre peut en bénéficier.
    Ils peuvent être utilisés pour améliorer des éléments tels que des animations, des formulaires et bien d'autres.

@Hixie , avez-vous passé du temps à utiliser Hooks, ou les feuilletez-vous pour prendre une décision ? Je ne sais pas quel pourcentage du temps de l'équipe Flutter est consacré à l'écriture d'éléments de framework par rapport à l'écriture d'applications pour les clients. Je soupçonne que les personnes qui écrivent des applications pour les clients aborderont cette question sous un angle légèrement différent de celui d'un développeur de framework. C'est-à-dire, comment cela me rend-il plus efficace et apporte-t-il plus de valeur à mes clients, pas si cela répond aux mêmes critères qu'une solution existante.

J'ai récemment introduit flutter_hooks avecfunctional_widget dans l'une de nos nouvelles applications populaires.

Il a considérablement réduit le code passe-partout et après avoir refactorisé tous ces widgets avec état désordonnés en fonctions minuscules avec des crochets, la base de code a diminué d'environ 70 %.

D'un point de vue supérieur, un widget fonctionnel avec un ensemble de crochets est comme une simplification impérative de la combinaison de plusieurs observables à l'aide de combineLatest dans RX. Mais au lieu d'énoncer explicitement tous les observables dans le préambule et d'avoir une fonction qui agit dessus, les crochets sont beaucoup plus flexibles parce que vous les intégrez dans le code où vous avez besoin de la valeur.

Mais, à la fin, chacun de ces widgets est comme une étape dans un flux RX.

Je ne pense certainement pas que nous devrions supprimer flutter_hooks. Je ne vois tout simplement pas ce que nous (l'équipe Flutter) pouvons fournir de plus précieux.

Les crochets sont aux widgets ce que les électrons sont aux atomes.

Je pense que si nous suivons cette métaphore, vous devriez considérer Flutter comme des quarks, ou peut-être des hadrons. Les électrons de Hooks sont une couche au-dessus.

@Hixie , avez-vous passé du temps à utiliser Hooks, ou les feuilletez-vous pour prendre une décision ? Je ne sais pas quel pourcentage du temps de l'équipe Flutter est consacré à l'écriture d'éléments de framework par rapport à l'écriture d'applications pour les clients.

Je n'ai pas utilisé Hooks moi-même. J'écris des applications avec Flutter. Je n'ai trouvé aucun besoin de quelque chose comme Hooks en le faisant. Comme indiqué ci-dessus, cependant, je ne pense pas que Hooks corresponde à mon style de développement (je préfère voir le passe-partout). Je ne voudrais certainement pas supprimer Hooks de quiconque souhaite l'utiliser.

Je ne vois tout simplement pas ce que nous (l'équipe Flutter) pouvons fournir de plus précieux.

Pour rendre les crochets vraiment utiles, ils ont besoin d'un plug-in d'analyseur et d'options de refactorisation personnalisées.
Ce n'est qu'avec ceux-ci que les crochets brillent vraiment.

Les crochets permettent une analyse statique très forte qui est impossible avec un StatefulWidget typique.
Cela rend la gestion de l'état local d'un widget plus sûre/plus évolutive. Pour moi, la réduction passe-partout n'est qu'un bonus.

Mais:

  • il y a _beaucoup de travail_, sur des API de très bas niveau.
  • l'interface du plugin d'analyseur n'est pas stable, manquante, presque inutilisée et non recommandée par l'équipe (car il y a une analyse effectuée pour chaque plugin)
  • flutter lui-même n'utilise pas l'API du plugin et l'implémente directement sur le serveur

Ainsi, en tant que package géré par la communauté, la probabilité d'avoir un outillage complet pour les crochets est très faible.

Je pense que si nous suivons cette métaphore, vous devriez considérer Flutter comme des quarks, ou peut-être des hadrons. Les électrons de Hooks sont une couche au-dessus.

Si Flutter est un quark, c'est aussi une galaxie.

Nous avons en effet des classes de très bas niveau comme Layer .
Mais il y a aussi une énorme quantité de classes de haut niveau comme Switch .

L'intégralité des bibliothèques Material et Cupertino peut être extraite sous forme de packages, puis de navigateur et d'objets liés au formulaire. Mais ils ne le sont pas.
Et les crochets sont quelques couches en dessous de ceux-ci.

Sans rapport, mais je crois fermement que Material et Cupertino ne devraient pas être dans la bibliothèque principale de Flutter car cela favorise un manque de bonnes interfaces positionnées quelque part entre les composants de très bas niveau et les composants de haut niveau Material. Si vous avez déjà essayé de créer une application sans bibliothèque de matériaux, c'est incroyablement difficile.

Les crochets ne visent pas vraiment à réduire le passe-partout. (Cela ne nous dérange pas non plus.) La valeur principale pour moi est de pouvoir encapsuler et composer une logique avec état.

const [value, setValue] = useState(0)
const debouncedValue = useDebounced(value, 1000)
const interpolatedValue = useSpring(debouncedValue, {
  friction: 10,
  mass: 20
})

Pouvoir acheminer des données entre eux sans se soucier de savoir s'ils contiennent ou non un état, extraire cette logique dans des crochets personnalisés, ou même appliquer le même crochet plusieurs fois, est très expressif. Et contrairement aux approches de type Rx, vous pouvez réellement parcourir tout le code sans creuser dans les combinateurs.

Pour rendre les crochets vraiment utiles, ils ont besoin d'un plug-in d'analyseur et d'options de refactorisation personnalisées.
Ce n'est qu'avec ceux-ci que les crochets brillent vraiment.

Je suis d'accord que nous devons soutenir cela. Cela devrait cependant être un bogue déposé contre le projet Dart GitHub. Je voudrais que nous déplacions les peluches spécifiques à Flutter hors de la base de code Dart, certainement.

L'intégralité des bibliothèques Material et Cupertino peut être extraite sous forme de packages, puis de navigateur et d'objets liés au formulaire. Mais ils ne le sont pas.

Oui, c'est probablement vrai aussi. Il y a des raisons pratiques pour lesquelles nous ne le faisons pas (par exemple, cela compliquerait le "Hello World" qui rendrait plus difficile de commencer à utiliser Flutter), mais nous pourrions néanmoins l'envisager. Encore une fois, cependant, c'est une question distincte que nous devrions déposer séparément si nous voulons l'examiner.

La valeur principale pour moi est de pouvoir encapsuler et composer une logique avec état.

C'est en effet très précieux. Il n'est pas clair que cela doive être dans le cadre de base cependant.

C'est en effet très précieux. Il n'est pas clair que cela doive être dans le cadre de base cependant.

Cela permettrait de déprécier certains mixins d'état de base.

Par exemple, AutomaticKeepAliveClientMixin est dans une position bizarre.
Nous devons appeler super.build , ce qui est très contre-intuitif. Et que super.build renvoie null qui ne fonctionnera pas avec les types non nullables.
Mais en tant que crochet, ces deux problèmes sont résolus.

De même, nous n'aurions pas besoin à la fois SingleTickerProviderStateMixin et TickerProviderStateMixin puisque les hooks sont réutilisables autant de fois que souhaité.

Alternativement, les crochets ont un aspect communautaire important. S'ils ne sont pas essentiels, les gens sont beaucoup moins susceptibles de créer et de partager des crochets personnalisés.

Nous n'utilisons pas réellement les crochets dans le cadre de base, car à mon humble avis, ils rendent les choses moins lisibles. Donc, les avoir dans le cadre de base n'aiderait pas à supprimer d'autres codes.

Alternativement, les crochets ont un aspect communautaire important. S'ils ne sont pas essentiels, les gens sont beaucoup moins susceptibles de créer et de partager des crochets personnalisés.

Si les crochets sont bons, les gens les utiliseront, qu'ils proviennent du projet open source Flutter ou du projet open source Hooks, par exemple.

Nous n'utilisons pas réellement les crochets dans le cadre de base, car à mon humble avis, ils rendent les choses moins lisibles. Donc, les avoir dans le cadre de base n'aiderait pas à supprimer d'autres codes.

Alternativement, les crochets ont un aspect communautaire important. S'ils ne sont pas essentiels, les gens sont beaucoup moins susceptibles de créer et de partager des crochets personnalisés.

Si les crochets sont bons, les gens les utiliseront, qu'ils proviennent du projet open source Flutter ou du projet open source Hooks, par exemple.

Cela ne semble pas une mauvaise idée. Les hooks peuvent s'exécuter en tant que projet open source séparé. L'équipe de base aura-t-elle la priorité sur l'exigence de changement de base du projet Hook ? À mon humble avis, c'est assez important pour le succès du projet de crochet.

Qu'est-ce que "l'exigence de changement de base" ?

Qu'est-ce que "l'exigence de changement de base" ?

Outils de développement.
Principalement à propos des plug-ins d'analyseurs, mais aussi potentiellement d'un système de plug-ins sur flutter/devtools.

Il y a beaucoup de travail là-dedans, qui ne peut pas être fait par la communauté.

Nous n'utilisons pas réellement les crochets dans le cadre de base, car à mon humble avis, ils rendent les choses moins lisibles. Donc, les avoir dans le cadre de base n'aiderait pas à supprimer d'autres codes.

Avec tout le respect que je vous dois, mais cela semble un peu ignorant. Vous devriez vraiment les essayer! Ils sont bien plus concis que de danser avec initState/dispose/setState/build pour chaque aspect de l'état.

Flutter est une question de composition et l'utilisation de crochets suit naturellement le modèle de composition où l'utilisation de mixins est à l'opposé de la composition.

J'imagine que nous continuerons à envisager de faire de l'analyseur extensible une priorité élevée. Malheureusement, il existe de nombreuses autres priorités plus élevées, telles que l'amélioration de l'expérience pour les tâches de base de la première heure et la mise en œuvre d'outils pour le changement non nullable par défaut.

Cela dit, je ne vois pas pourquoi cela ne pourrait pas être fait par des non-Googlers. Flutter et Dart sont tous deux des projets open source et de nombreuses choses sont mises en œuvre par des non-Googlers.

Cela dit, je ne vois pas pourquoi cela ne pourrait pas être fait par des non-Googlers. Flutter et Dart sont tous deux des projets open source et de nombreuses choses sont mises en œuvre par des non-Googlers.

Nous parlons de mois de travail sur plusieurs projets, pour des choses que l'équipe considère comme des "fonctionnalités de faible priorité", avec de nombreux changements majeurs. Et les projets impactés sont de très bas niveau avec presque aucune documentation publique.

L'investissement requis et les risques de rejet / d'être coincé au milieu sont beaucoup trop élevés. Surtout quand nous n'en tirons pas d'argent.

Donc, même si je comprends votre point de vue, il est extrêmement peu probable

Existe-t-il une feuille de route à ce sujet ? Avez-vous une idée si et quand il pourrait être possible pour les crochets d'atterrir en flottement ?

Si Flutter réussit (ce que j'espère), dans 1 an, chaque développeur React essayant de s'intégrer à Flutter criera quand il découvrira qu'il n'y a pas de support de première classe pour les crochets ici.

L'équipe Flutter a pris une bonne décision en copiant le modèle React basé sur les classes, mais c'est une chose du passé maintenant, les composants fonctionnels et les crochets sont l'avenir, l'équipe Flutter devrait se réveiller à cette nouvelle réalité si elle veut rester à la hauteur .

Précis comme cgarciae l'a indiqué, la communauté React passe au crochet et au composant fonctionnel à l'avenir. Et cela rend Flutter obsolète, car le modèle de programmation et la productivité ne seraient pas à la hauteur des autres solutions de développement multiplateforme.

Après avoir essayé à la fois la réaction et le flottement récemment, le crochet manquant dans le flottement laisse un grand trou en ce qui concerne la productivité, la cohérence et la maintenabilité de l'appartement en comparaison. Cela n'aiderait pas l'organisation à adopter le flutter dans un nouveau projet, ou à convaincre les gens de passer de la solution de base React au flutter qui en valait la peine.

Je comprends parfaitement quand quelqu'un construit un ensemble d'outils, une implémentation de framework de bas niveau, le code passe-partout peut ne pas sembler vraiment un problème. Mais si un développeur d'application a besoin d'écrire beaucoup de passe-partout "inutile" pour que quelque chose fonctionne, l'effet n'est pas souhaité.

Selon l'angle sous lequel les gens examinent un problème spécifique, le compromis/l'équilibre peut sembler différent. Ne pas fournir d'outils appropriés ou certaines fonctionnalités peut rendre la mise en œuvre interne du framework plus propre, mais cela décharge simplement la responsabilité du consommateur du framework, rend la mise en œuvre côté client plus compliquée et maladroite qu'elle ne devrait l'être, ce qui à son tour n'aide pas l'adaptation d'un donner cadre. Pour un développeur d'applications, la productivité et la cohérence sont importantes, une approche/norme unifiée est importante pour le travail d'équipe et la communauté. Une approche holistique devrait toujours considérer les personnes vivant de l'autre côté de la clôture.

Les hooks devraient être faciles à mettre en œuvre, mais les widgets fonctionnels sont plus difficiles. Cela nécessiterait des types d'union dans Dart puisque vous devez exprimer quelque chose comme :

'Widget | Fonction Widget (BuildContext)'.

les widgets fonctionnels sont plus difficiles. Cela nécessiterait des types d'union dans Dart

C'est loin d'être suffisant.
Reste la question de :

  • comment passer des paramètres aux fonctions? Curry?
  • une fois dans l'arborescence des widgets, deux widgets fonctionnels doivent avoir un runtimeType différent
  • comment brancher des widgets avec devtools ? (la méthode debugFillProperties des widgets)

J'y ai pensé pendant un certain temps. Je ne vois pas de solution simple pour les widgets fonctionnels.
La seule chose à laquelle je peux penser est une combinaison de plugins de génération de code et d'analyseur (pour avoir une bonne définition et tout).

En fait, la partie génération de code nous a fait abandonner votre packagefunctional_widget. Cela crée juste trop de sauts lors de la révision du code. Donc, ça ne volerait pas pour moi...

Cela crée juste trop de sauts lors de la révision du code

C'est pourquoi j'ai mentionné un plugin d'analyseur.

Avec un plug-in d'analyseur personnalisé, nous devrions être en mesure de :

  • vérifier que la fonction n'est pas utilisée directement et que la classe est préférée
  • avoir un bon "aller à la définition"/"peek"/..., de sorte que cliquer sur la classe redirige vers la fonction

Cela devrait résoudre tous les problèmes.
Mais nous revenons au "hooks a besoin d'un système de plug-in d'analyseur approprié".

Peut-être que l'introduction de widgets functional n'est pas nécessaire :

Disons que l'utilisation de crochets n'est autorisée qu'à l'intérieur de la méthode StatelessWidget build .

D'un point de vue technique - peu importe (pour autant que je puisse penser maintenant) si c'est la classe ou la fonction. L'important est de ne pas mélanger les classes avec état et les crochets. Sous le capot, le moteur de rendu flutter peut toujours compter les crochets et leur ordre s'ils sont appelés dans la méthode build et le gérer correctement.

À l'avenir, si la création de widgets fonctionnels était possible, ce n'est pas un changement radical. De plus, il serait rétrocompatible, car il ne casse pas les applications existantes.

Je ne vois aucun problème évident avec l'utilisation de crochets à l'intérieur StatelessWidget qui enlèverait les avantages de l'utilisation de crochets comme la composition.

Je ne sais pas, cependant, comment cela se comparerait à des cas comme useCallback etc. de réagir par rapport à la possibilité d'utiliser des méthodes d'instance de toute façon

L'argument "nous devons ajouter ceci car les développeurs de React seront en colère" n'est pas valide. (voir plus de 500 commentaires sur la discussion JSX).

Flutter est Flutter, et il a son propre langage et ses propres modèles de conception.
Je pense que nous ne devrions pas ajouter des éléments au framework juste pour le rendre plus familier aux développeurs de React, ils peuvent utiliser le package s'ils le souhaitent.

J'ai lu la discussion et je pense que @Hixie en tant que développeur de framework Flutter vient de voir son côté du problème (mise en œuvre et ... des trucs) et avait moins de perspective sur la façon dont les développeurs d'applications Flutter (qui sont son public cible) pensent et l'utilisent dans leur développement.

En tant que développeur Android, j'ai eu un tel problème, j'essaie de développer une excellente structure back-end pour mes applications sans aucune idée de ce que les utilisateurs de mon application ressentiront lorsqu'ils verront mon interface utilisateur laide et difficile à comprendre UX.

Comme d'autres l'ont dit avant, les crochets sont super. peu importe qui l'introduit, que ce soit FB diabolique ou Apple.
ça marche. il sépare la logique d'état et leurs cycles de vie. nous pouvons créer d'autres crochets utiles les uns sur les autres, publier des widgets, des apis, des outils indépendants, ... à partir des états de l'application, réutiliser nos pré-produits dans d'autres projets, ....

Et je pense que si le pré-ajout d'une ligne dans pubspec.yaml pour importer du matériel ou cupertino est difficile à créer une simple application hello-word !!!, il n'y a rien à discuter ici.
Mais comme StatefullWidget est très important pour l'écosystème de flutter, les crochets et leur pertinence ont plus d'importance à l'avenir de flutter et de son écosystème et de la communauté des développeurs de flutter.

Imaginez simplement comment le développement d'applications flottantes sera plus simple, à l'épreuve des bogues, facile à comprendre, extensible, lisible, débogable, portable, ... (tout bon mince plus capable ici svp 😁) avec des crochets directement pris en charge avec le noyau (ou quelque chose au milieu entre le noyau et certains widgets complexes comme le matériel, ...) spécialement officiel.

Pour mieux comprendre mon point de vue, regardez à quel point le développement d'Android était horrible avec Java et les bibliothèques de support et à quel point Kotlin était chic et agréable.
Cela ouvre également la porte à d'autres bonnes choses comme Coroutines, Flow, le support AndroidX + Kotlin, le nouveau système d'interface utilisateur (Compose)
Même cela a poussé la communauté Java à démarrer et à implémenter les futurs kotlin dans leur éco.

Alors s'il vous plaît laissez tomber n'importe quel tampon dans les crochets, et réagissez et faites-le

Le manque de prise en charge officielle des hooks est la seule raison pour laquelle je ne suis pas passé de React Native.

Les crochets rendent la vie tellement plus facile que je ne veux plus jamais l'écrire à l'ancienne

Une partie étonnante des "crochets natifs" est que nous pouvons porter de nombreux StatefulWidget internes ou ... vers cette forme simple et compréhensible.
Aussi, en tant qu'équipe Flutter, Flutter et Dart sont conçus pour une courbe d'apprentissage facile à utiliser, facile à comprendre et rapide. Tout cela peut être vrai et meilleur avec Native Hooks.
Et la méthode (initState/dispose/setState/build) n'est pas dans ce chemin. (nous pouvons en avoir besoin dans le backend de la plate-forme, mais pas pour les nouveaux développeurs ou même les concepteurs qui souhaitent utiliser du code uniquement pour décrire leurs idées (pas de logique complexe))

Ma lecture sur ce fil est qu'il y a beaucoup de gens enthousiastes à l'idée d'utiliser des crochets dans Flutter, et quelques questions ouvertes concernant les crochets :

  • Impact/mesure des performances - en particulier, l'efficacité de toujours appeler des fonctions par rapport à voir que cet état peut être réutilisé sans appeler une nouvelle fonction.
  • Capacité (incapacité ?) à bien jouer avec les touches globales et/ou à se déplacer efficacement dans l'arbre.
  • Support analyseur/peluches spécifique aux hameçons.
  • Capacité à fonctionner aussi bien avec le rechargement à chaud que les vieux widgets avec état/sans état.
  • Besoin potentiel d'une API de framework supplémentaire.

Je suis sûr que toutes ces questions peuvent être abordées, mais les aborder n'est pas anodin. Le problème n'est pas tant "les hooks doivent-ils être dans le framework ou les hooks doivent-ils vivre dans un package séparé". Dans une certaine mesure, cette décision est déjà prise - flutter_hooks est disponible sur pub.dev depuis plus d'un an maintenant et semble être un package populaire. C'est que faire de flutter_hooks une expérience vraiment raffinée nécessitera un travail et un investissement importants, au-delà de ce qui a déjà été fait.

Une grande partie de ce travail _a_ déjà été fait pour les classes de framework de base, et il a fallu plusieurs années à plusieurs équipes d'ingénieurs ainsi qu'à plusieurs contributeurs open source pour en arriver là où il en est. Parfois, il semble qu'il y ait une illusion de "si nous le fusionnons simplement avec le repo X, toutes les choses non résolues se résoudront!" Mais la façon dont ces choses se produisent est que les gens qui sont enthousiastes à leur sujet font le travail de les mettre en œuvre. @rrousselGit a déjà fait beaucoup de travail autour de cela, et il semble que plusieurs autres contributeurs l'aient également fait dans le référentiel de crochets.

Ce que j'essaie de dire en un mot, c'est que les crochets peuvent très bien fonctionner sans être dans le référentiel Flutter, être dans le référentiel Flutter n'accélérera pas la résolution de ses problèmes en suspens, et que quiconque veut voir Hooks fonctionner dans Flutter est tout à fait habilité à y parvenir.

Eh bien, à mon avis, les crochets devraient plutôt être une fonctionnalité de langage similaire aux générateurs de synchronisation / asynchrone .
Cela ne doit pas du tout être lié au flottement.

Les problèmes que les hooks résolvent sont :

  • gestion d'état déclarative et réactive.
    State est impératif
  • composition de l'état pour fixer DRY.
    Tous ces XXController doivent être créés + mis à jour + éliminés et il n'y a aucun moyen de factoriser cette logique.
  • lisibilité, car cela n'implique pas une imbrication sans fin de fonctions/widgets pour obtenir ce résultat

Mais une syntaxe alternative pourrait être :

class MyWidget extends HookWidget {
  const MyWidget({Key key, this.title}): super(key: key);

  final String title;

  Hook<Widget> build() hook* {
    final (flag, setFlag) = yield false;
    final (animationController) = yield* useAnimationController(duration: const Duration(seconds: 2));

    // TODO: do something with animationController
    return CheckBox(
      value: flag,
      onChanged: setFlag,
    );  
  }
}

Hook<AnimationController> useAnimationController({required Duration duration}) hook* {
  final (tickerProvider) = yield* useTickerProvider();
  final (animationController) = yield AnimationController(duration: duration, vsync: tickerProvider);
  animationController.duration = duration;

  return animationController;
}

Cela produit le même effet que flutter_hook, mais est indépendant du flottement et avec plusieurs facteurs d'optimisation que flutter_hook ne peut pas faire.

Et cela permet essentiellement à _n'importe quoi_ d'utiliser des crochets, pas seulement des widgets.

C'est une idée intéressante. Il semble qu'il y ait plusieurs demandes de fonctionnalités de langage (quelque chose comme defer de Go, quelque chose comme un destructeur déterministe de C++, une certaine capacité à composer implicitement des fonctions dans des objets) - mais ce n'est pas vraiment le bon endroit pour suivre cela.

Je pense qu'il serait utile d'identifier les points douloureux que les gens rencontrent en n'ayant pas quelque chose comme des crochets dans Flutter, et de classer les problèmes spécifiquement à propos de cette douleur sans choisir une solution pour commencer. Il est tout à fait possible, cependant, que certains de ces points faibles soient simplement des choses que le cadre force afin d'atteindre des objectifs de performances, de qualité ou de compromis d'utilisabilité (comme dans, nous pourrions améliorer le point de douleur X au coût d'aggravation du point douloureux Y).

Dans l'état actuel des choses, je vais fermer ce sujet. Il existe un bon package qui traite cette solution spécifique, et la solution elle-même n'est pas prête à fusionner dans le cadre dans son état actuel (pour les raisons décrites ci-dessus), et il n'est pas clair que la solution serait jamais vraiment bénéficier d'être fusionné dans le cadre.

@dnfield Hooks fonctionne bien "en famille", uniquement lorsque vous avez couvert tous les principaux domaines d'exigences.

Il serait inutile d'utiliser des crochets d'état si vous vous heurtiez au mur lorsque vous avez besoin d'une sorte d'effet après un changement d'état.

De par sa conception, tout crochet nécessite des modifications importantes au sein du moteur de rendu ou l'introduction d'un nouveau type de composant principal.

Un tel effort n'en vaut pas la peine pour un seul type de crochet (point douloureux), donc je dirais qu'il est impossible de résoudre ce problème en tant qu'ensemble de problèmes plus petits. Le crochet unique ne vaut pas la peine de passer des composants avec état et ne vaut certainement pas la peine d'introduire des changements significatifs dans le moteur de rendu.

Si ce problème est censé dire "Je veux que Flutter ressemble plus à React mais aussi à Flutter", je ne sais pas à quel point il est exploitable - et un problème GitHub n'est probablement pas la bonne façon de suivre une telle chose de toute façon, même si nous accordons une telle chose a du sens à suivre.

Autrement dit : s'il s'agit d'une demande de réécriture du noyau de Flutter, ce n'est pas la bonne façon de l'aborder. Je ne sais pas quelle serait la bonne façon de l'aborder, mais cela commencerait probablement par simplement bifurquer le référentiel et entreprendre un effort massif.

J'ai un sentiment étrange lorsque des crochets sont présentés à des personnes qui ne les connaissent pas et qui maintiennent d'autres technologies.

Il semble que la réponse soit souvent quelque chose comme "si vous voulez que X soit comme React, utilisez react".

Mon opinion est que les crochets sont une solution générique à de nombreux problèmes frontaux où vous devez réutiliser une logique de données complexe. C'est plus comme une idée qui pourrait être utilisée dans n'importe quelle technologie.

Les crochets, cependant, nécessitent une sorte de changement dans la réflexion sur le flux de données avant que leur valeur ne soit pleinement visible. Je pense que cela pourrait être un gros problème lors de la "demande" de crochets dans d'autres frameworks.

Je pense que l'équipe React a fait un excellent travail en essayant d'expliquer les crochets, mais peut-être que cela crée une certaine résistance parce que les crochets semblent fortement liés à React.

Je pense que React est mentionné si souvent à côté des crochets simplement parce que c'est là qu'ils ont été inventés. React est également la meilleure source d'informations sur les crochets (jusqu'à présent).

En général, je décrirais le "point douloureux" comme l'impossibilité d'utiliser un modèle de composition pour la logique des données directement dans Flutter. Les crochets ne sont qu'un exemple de permettre cela.

Je comprends également que l'introduction de crochets est une tâche énorme et je dois dire que je ne suis pas disposé à entreprendre.

Personnellement, je ne comprends pas l'argument "la communauté a tenté de résoudre ce problème, nous n'avons donc rien à faire".

Un correctif communautaire ne signifie pas qu'il ne pourrait pas être mieux fait par Google.
Prenons l'exemple des expressions à l'intérieur des collections.
La communauté pourrait le "réparer" en bifurquant Row/Column/ListView/... pour prendre en charge null .
Mais Google l'a corrigé en modifiant la langue.

Aussi, Flutter lui-même le dit : Flutter est inspiré de React.
Cela peut être vu par la façon dont une grande partie de la façon dont un Widget est utilisé est essentiellement la façon dont une classe React est utilisée.

Bien que cela ne signifie pas que Flutter doit correspondre à React, je m'attendrais à ce que l'équipe Flutter surveille au moins de près les mises à jour de React et son écosystème.
Cela devrait au moins fournir une meilleure réponse à la raison pour laquelle "nous ne voulons pas de crochets dans le cadre" autre que l'argument de la communauté.

@rrousselGit @pie6k

Personnellement, je trouve l'API Hooks, telle qu'elle est dans React, assez difficile à saisir. Je préfère les méthodes de cycle de vie et leur dénomination descriptive.

Je sais que c'est un "problème de moi", mais je soutiens le commentaire de @dnfield disant que nous devrions peut-être prendre les problèmes et mettre en œuvre des solutions différemment.

De plus, je suis rarement arrivé à une situation où deux widgets distincts doivent partager la même logique (c'est ce que j'ai compris comme principal avantage de Hooks ?)

Et à propos de Flutter inspiré par React, ça va, mais cela ne signifie pas qu'il suivra tous les modèles et l'architecture de React pour toujours.
L'un des principaux problèmes que j'ai rencontrés avec React est qu'il y a tellement de façons différentes de faire quelque chose, et les "pratiques recommandées" changent quotidiennement. Je comprends que c'est la nature du génie logiciel, mais je pense toujours que s'il y a quelque chose de mauvais dans les méthodes existantes, il faut essayer de les améliorer… au lieu d'empiler différentes façons d'obtenir la même chose.

J'espère que cela vous offre une perspective légèrement différente et n'offense personne.

Un grand respect pour vos contributions à la communauté Flutter.

Dommage que ce sujet soit clos. Cela donne l'impression que l'équipe Flutter ignore les crochets ou ne se soucie pas de l'état actuel des modèles de conception (j'espère que ce n'est pas le cas). Ce n'est bon pour aucune technologie, les gens qui investissent des centaines d'heures veulent savoir que ce qu'ils utilisent est de premier ordre ou peut être à égalité avec cela, et en ce moment, le modèle le plus productif est les crochets et Flutter est à la traîne, mais il n'a même pas été pris en compte ou ignoré en faveur d'une alternative convaincante meilleure par les mainteneurs.

@cgarciae personne n'est ignorant, @dnfield a clairement dit - au lieu d'essayer d'intégrer des solutions existantes, d'ouvrir les problèmes pour les problèmes correspondants que vous avez, l'équipe Flutter les évaluera et proposera éventuellement une solution qui convient encore mieux à Flutter.

C'est une fonctionnalité que la communauté a fortement demandée et va demander. Si le problème n'est pas au bon endroit, avez-vous une demande de fonctionnalité pour enregistrer l'exigence de la communauté ?

@SpajicM Je suis tout à fait d'accord avec "non" comme réponse.
Ce avec quoi je ne suis pas d'accord, c'est la justification actuelle.

Quelques notes:

  • Les crochets sont une caractéristique importante de React, le père de Flutter
  • ce problème est l'un des plus votés sur Flutter
  • flutter_hooks est assez populaire
  • Dan Abramov de l'équipe React a proposé de discuter avec l'équipe https://github.com/flutter/flutter/issues/25280#issuecomment -456404333

Ceux-ci devraient donner des discussions intensives sur les crochets. Pas nécessairement les mettre en œuvre, mais au moins les explorer.

En fin de compte, cela se résume à un problème de communication.

  • L'équipe Flutter a-t-elle contacté l'équipe React comme proposé par Dan Abramov ?
  • L'équipe a-t-elle expérimenté le crochet dans React ?
  • Une alternative aux problèmes résolus par les crochets a-t-elle été envisagée ?

Nous, en tant que communauté, n'en savons rien.

Poussé un peu plus loin, je pense qu'il est ironique que la communauté ait été suggérée de diviser ce problème en "quels sont les problèmes que les crochets résolvent", alors que l'équipe React elle-même a proposé d'expliquer à l'équipe Flutter quels sont ces problèmes.

@rrousselGit Je pense que l'idée sous-jacente est d'entendre les problèmes du côté spécifique à Flutter, directement des utilisateurs, et de prendre cela comme point de départ au lieu de prendre le raisonnement de React, cela ne veut pas dire que leur contribution ne serait pas précieuse.

Mon avis est qu'il serait bon d'avoir un moyen de séparer clairement la logique et la conception du widget - donc je suis d'accord qu'il y a un problème à résoudre , mais la façon dont React le fait est quelque peu déroutante pour moi et je souhaite que la future solution de Flutter ait un changement de paradigme/courbe d'apprentissage moins dramatique. Je n'ai pas d'idée en tête, mais je suis sûr que la communauté et une équipe pourraient proposer quelque chose si elles étaient ouvertes d'esprit et non obsédées par l'implémentation existante de Hooks.

Je suppose que la prochaine étape consiste à ouvrir un problème appelé :

_"Flutter a besoin d'un meilleur moyen d'isoler la logique des widgets"_

Je pense que https://svelte.dev/ a une approche différente et meilleure pour résoudre ces problèmes. Dans un premier temps, l'équipe Flutter doit se rendre compte qu'il y a un problème et que nous avons besoin d'une solution.

Je suis nouveau dans le flutter et ce que je pense, c'est que l'API a beaucoup de passe-partout. Je pensais que Dart avait un générique, j'ai l'impression de programmer en Go où il est plus courant/plus facile de faire un copier-coller. J'espère qu'il y aura une énorme refactorisation lorsque NNDB a atterri, en particulier en utilisant la méthode d'extension au maximum. L'abstraction progressive de l'API via quelque chose comme une méthode d'extension pourrait valoir la peine d'être explorée.

À mon humble avis, l'équipe Flutter tient trop à l'idée de "tout est un widget". Les widgets sont parfaits pour les éléments visuels et les mises en page, mais pas pour l'obtention/le traitement des données. Au lieu d'encombrants FutureBuilder , StreamBuilder , TweenAnimationBuilder etc. Je préférerais une API fonctionnelle :

Widget build(BuildContext context) {
    final a = useFuture(someFuture);
    final b = useStream(someStream);
    if (a.value == null || b.value == null) {
        return CircularProgressIndicator();
    }

    final value = a.value + b.value;
    final smoothedValue = animate(value, duration: Duration(milliseconds: 100), curve: Curves.easeInOut);

    return Slider(
        value: smoothedValue
    );
}

En fait, Flutter utilise déjà des crochets à certains endroits. Donc au lieu de plus "Fluttery"

MediaQueryGetter {
    builder: (BuildContext context, MediaQueryData data) {
        ...
    }
}

vous pouvez utiliser
final data = MediaQuery.of(context);

Malheureusement, ce mécanisme (abonnement lors de l'obtention) ne fonctionne qu'en conjonction avec InheritedWidget.

Je ne sais pas combien de progrès nous pouvons encore faire à ce sujet, mais je voulais aborder quelques points que je vois ici :

  1. Il est beaucoup plus difficile d'évaluer une _solution_ que d'évaluer un _problème_ dans un problème GitHub. Lorsque vous présentez une solution, il y a une barre beaucoup plus haute à atteindre pour être acceptée. Vous devez montrer que la solution est bien conçue, vaut l'effort qu'elle implique et qu'elle résout un ensemble de problèmes réels proportionnés au niveau d'effort requis (y compris non seulement le prototypage et la mise en œuvre initiaux, mais également la maintenance et la qualité continues) . En d'autres termes, un problème où nous discutons d'un problème spécifique autour de la gestion des données et de l'état des widgets est susceptible de conduire à un certain nombre de solutions, dont certaines pourraient être adoptées dans le cadre, dont certaines pourraient devenir des packages tiers, et d'autres ce qui serait bien mais coûte trop cher.

  2. Les ingénieurs de Google travaillant sur Flutter et Dart cherchent toujours à l'améliorer et sont généralement toujours occupés. Il en va de même pour les nombreux ingénieurs non Google qui contribuent à Flutter. La fermeture de ce bogue ne signifie pas qu'aucun ingénieur de Google ne travaillera jamais à améliorer le fonctionnement des crochets avec Flutter. Le fait que le paquet hooks appartienne à un membre de la communauté ne diminue en rien la qualité du paquet ou sa valeur - ni ne diminue la capacité à répondre à certaines des lacunes identifiées dans ce bogue, par exemple un meilleur support pour l'analyse/linting

  3. Il existe différentes raisons d'accepter ou de rejeter une fonctionnalité. Parfois, c'est que la fonctionnalité est vraiment cool, mais ne correspond pas tout à fait à l'architecture. Parfois, c'est que la fonctionnalité semble bonne en surface, mais présente des lacunes majeures qu'elle n'a pas résolues. Parfois, la fonctionnalité est excellente, elle nécessiterait suffisamment d'efforts, mais la quantité d'efforts qu'elle coûte l'emporte sur la valeur qu'elle offre aux utilisateurs, ou prendrait du temps nécessaire pour d'autres fonctionnalités encore plus précieuses. Pour Flutter en particulier, c'est parfois simplement que nous avons une architecture à plusieurs niveaux qui permet l'extension par des packages tiers, et souvent il est préférable de préserver la pose et de permettre à des tiers de faire un excellent travail plutôt que d'inclure quelque chose de nouveau dans le framework. Nous le faisons nous-mêmes dans des packages comme le nouveau package d'animations qui se trouve sur https://github.com/flutter/packages/tree/master/packages/animations.

Enfin, j'ai été de l'autre côté. Je suis moi-même responsable d'un paquet et j'ai eu des propositions de fonctionnalités refusées qui auraient rendu mon paquet plus facile à maintenir ou à développer. Mon seul conseil est que si vous avez un super package que vous aimez, continuez à travailler dessus. D'autres personnes le reconnaîtront et aideront également, qu'il soit inclus dans ce dépôt ou non.

Le nouveau ComposeUI d'Android a des états de type hook : (preview2)

val state = remember { CardDesignerState() } // react: let state = useState(CardDesignerState())
val thing = stateFor<T?> { null } // react: let thing = useState()

le nouveau SwiftUI d'iOS a également des choses similaires (mais c'est en interne):

// from https://developer.apple.com/tutorials/swiftui/animating-views-and-transitions
Image(systemName: "chevron.right.circle")
                        .imageScale(.large)
                        .rotationEffect(.degrees(showDetail ? 90 : 0))
                        .scaleEffect(showDetail ? 1.5 : 1)
                        .padding()
                        .animation(.easeInOut)

imaginez que l'interface utilisateur rapide d'iOS utilise onCreate, onInit, onUpdate, onExit, ... 🤢

mais le meilleur framework (bien sûr c'est Flutter) résiste encore trop à l'idée d'utiliser des hooks, pourquoi ?
Parce que ça ressemble à React/ReactNative !!! ou quelques citations étonnantes de l'équipe de maintenance :

Je préfère voir le passe-partout

évidemment contre l'idée flottante d'écrire une interface utilisateur avec une syntaxe déclarative

Je pense que hooks mixin est une bonne solution.
Ayez des hooks où vous voulez et ne touchez pas aux codes et au framework des développeurs à l'ancienne.
Mais cette idée et toutes les autres grandes idées nécessitent une forte intégration avec les bibliothèques de base et il est bon de voir les responsables de base prendre en charge ces fonctionnalités de première classe.
Je peux également imaginer un avenir après l'intégration des crochets, que de nombreuses bibliothèques de framework de haut niveau (comme le matériel) prennent en charge et même utilisent en eux.

Flutter pourrait être plus beau :

// this is just scratch, not a complete and true use-case
build(context) {
    final angle = useAnimation(2*PI, 0, 5 /*seconds*/);
    return Image.from(myAwesomeImage)
        .padding(8)
        .scale(2.5)
        .rotate(angle);
}

@HKhademian totalement d'accord. Le manque de support de première classe pour tout ce qui ressemble à un crochet (ou en d'autres termes - tout ce qui permet une composition appropriée de la logique métier réutilisable) est en fait la seule raison pour laquelle je n'ai pas choisi Flutter pour mon dernier projet.

2. Le fait que le paquet hooks appartienne à un membre de la communauté ne diminue en rien la qualité du paquet ou sa valeur - ni ne diminue la capacité à répondre à certaines des lacunes identifiées dans ce bogue, par exemple un meilleur support pour l'analyse / peluchage

Les membres de la communauté ont-ils des paquets fantômes ? Oui. Google va-t-il utiliser le noyau fantôme de Flutter ? Eh bien, d'après votre position ici, il semble que cela devrait être une possibilité. Affirmer que Flutter de base est tout aussi viable pour la consommation que les packages communautaires est … au mieux faux et au pire un mensonge.

De plus, il a été démontré à maintes reprises qu'à moins qu'il n'y ait l'adhésion de @Hixie , qui a démontré une affinité pour l'utilisation des préférences personnelles pour annuler les demandes de la communauté, peu importe ce que la communauté veut ou a besoin. Sans adhésion, cela ne se fait pas. Et si ce n'est pas le cas, alors le processus de décision est trop opaque pour voir le contraire.

Ce qui m'intéresse, c'est que les personnes qui décident si les fonctionnalités vivent ou meurent semblent avoir très peu d'expérience commerciale dans la création d'applications mobiles. Ce point de vue donnera toujours le meilleur aperçu du sucre à mélanger dans Flutter.

Je pense que nous avons besoin d'un processus formalisé pour décider quelles fonctionnalités intégrer à Flutter, ce qui donne plus de poids à la communauté pour contribuer au processus de prise de décision. Évidemment pas à 100 %, mais pour le moment, on a l'impression que c'est environ 5 %, et un super floconneux de 5 %. @timsneath

Il est beaucoup plus difficile d'évaluer une solution que d'évaluer un problème dans un problème GitHub

L'équipe React a proposé d'expliquer son raisonnement derrière Hooks au tout début de ce numéro.
Cela devrait couvrir entièrement la nécessité d'expliquer pourquoi les hooks sont nécessaires, car personne n'est mieux placé pour expliquer les hooks que l'équipe React elle-même.

Luke, je respecte et apprécie votre passion, mais s'il vous plaît, arrêtez les attaques ad hominem. Nous travaillons tous pour essayer de construire la meilleure plate-forme possible, en faisant toutes sortes de compromis basés sur la capacité des ressources, la recherche des utilisateurs, les commentaires des parties prenantes, les besoins des clients et les commentaires de la communauté.

Soyez gentil, s'il vous plaît. https://github.com/flutter/flutter/blob/master/CODE_OF_CONDUCT.md

Aucune attaque ad hominem prévue, merci pour les commentaires. Selon le CoC, nous devrions peut-être nous réunir pour discuter de ce que j'essaie de communiquer.

Les personnes qui ne sont pas d'accord devraient se réunir, essayer de comprendre les points de vue de l'autre et travailler pour trouver un design qui réponde aux préoccupations de chacun.

Y a-t-il eu une mise à jour à ce sujet, ou où pouvons-nous coordonner une solution ? Je me heurte à cela avec mes projets Flutter, en particulier avec les animations et les transitions. Les crochets aident à encapsuler cet état initState et dispose , entre autres, dans une seule fonction et à utiliser simplement cette fonction au lieu de tout configurer.

Il semble, au moins pour un observateur / utilisateur extérieur de Flutter plutôt que pour un responsable de plugin, qu'il y a eu des préoccupations légitimes qui ne donnent pas l'impression d'être écoutées, comme l'autre problème avec Flutter Overlays (# 50961 ), et ils semblent être rejetés comme n'étant pas de vrais problèmes pour les utilisateurs, plutôt que pour les responsables. Encore une fois, sans manquer de respect aux responsables, ce n'est que mon opinion en tant que personne lisant ce fil de discussion avec désinvolture, je ne connais pas trop d'autres problèmes qui pourraient être différents.

Ceci étant dit, comment procéder plus globalement pour penser des solutions aux problèmes que les utilisateurs semblent avoir légitimement ? Je sais que Rust a un système RFC intéressant qui semble bien fonctionner pour concevoir de nouvelles solutions.

@satvikpendem Le processus RFC ici consiste à déposer un bogue décrivant le problème, puis une fois le problème clairement décrit, à discuter des solutions possibles.

Il semble que les problèmes aient été expliqués jusqu'à présent, alors les solutions peuvent être discutées maintenant, d'après votre commentaire. Que pouvons-nous faire ensuite, existe-t-il d'autres solutions qui fonctionnent mieux que les crochets ou quelque chose de similaire ?

Si vous me faites part du numéro de bogue, je peux vous dire si le problème décrit un problème avec suffisamment de détails pour qu'il soit logique de commencer à discuter des solutions possibles.

@hixie https://github.com/flutter/flutter/issues/51752

Je pense aussi que nous devrions avoir un suivi du commentaire de Dan : https://github.com/flutter/flutter/issues/25280#issuecomment -456404333
Quel a été le résultat de cette discussion ?

Salut Remi, merci beaucoup pour le bug #51752. Je sais que vous avez investi une tonne de temps dans cet espace et fourni des packages très précieux ici. Merci x1000 pour ça !

Pour réitérer le commentaire de @dnfield , il semble que nous ne nous soyons pas encore alignés sur l'espace du problème et sa signification. Le bogue ci-dessus est une étape utile vers cet objectif et/ou pour discuter des approches potentielles du problème. Votre question de suivi ici suppose qu'une conversation avec l'équipe React est la première étape à partir d'ici, mais si nous n'avons pas encore d'alignement sur l'espace du problème, cela semble prématuré.

Peut-être pouvons-nous montrer des exemples complets d'applications qui ont de tels problèmes qui seraient résolus avec des crochets. Nous ne les réécrirons pas nécessairement avec des crochets, mais montrerons simplement combien il y a de copier-coller. Serait-ce quelque chose qui se prête à la discussion, @timsneath ? Ou pensez-vous à autre chose ? J'essaie de comprendre comment montrer l'espace du problème aussi clairement que possible.

:wave: @timsneath
Pour être honnête, je ne comprends pas très bien pourquoi discuter avec l'équipe de React serait prématuré.

Même sans que la communauté ne demande des crochets, une discussion avec l'équipe React serait toujours très utile.
React partage de nombreuses similitudes avec Flutter, et ils ont quelques années d'expérience supplémentaires dans le traitement d'objets de type Widgets.

Discuter avec eux ne peut qu'apporter des avantages aux deux parties.

Par exemple:
Après avoir créé flutter_hooks, j'ai été contacté par Dan pour discuter de la façon dont j'ai géré le rechargement à chaud des crochets.
Ma réponse a été "Il n'y avait presque rien à faire car Flutter utilise un langage typé".
Quelques mois plus tard, ils ont amélioré le rechargement à chaud de React en générant quelque chose de similaire aux types avec Babel

Je suis sûr que si l'équipe Flutter et React discutaient, bon nombre de ces interactions pourraient se produire et les deux technologies progresseraient.

Quelques questions ouvertes qui pourraient être posées sans problème particulier :

  • Pourquoi crochets?
  • Pourquoi le mode suspense/simultané ?
  • Pourquoi des portails ?

@satvikpendem Le processus RFC ici consiste à déposer un bogue décrivant le problème, puis une fois le problème clairement décrit, à discuter des solutions possibles.

Cela signifie-t-il que toutes les discussions qui ne sont pas un bogue sont ignorées ? Je pensais que le but de RFC était pour des choses qui ne sont pas des bogues, mais généralement pour étendre des choses plus subjectives comme l'expérience des développeurs ou la sémantique des outils.

Si quelqu'un dit : "Je pense que nous devrions avoir des crochets, car ils deviennent idiomatiques dans plusieurs frameworks et que les gens signalent une expérience et une productivité améliorées", c'est une discussion valable à avoir, mais ce n'est pas un bogue reproductible.

Je suis absolument certain que personne n'a dit "les discussions qui ne sont pas un bogue seront ignorées". Allez, travaillons ensemble de bonne foi, en nous traitant avec respect et courtoisie. Nous faisons tous de notre mieux ici, mais avec beaucoup d'autres bugs concurrents, des conceptions et des idées en compétition pour notre attention :)

@lukepighetti , ironiquement, "nous devrions avoir des crochets parce que d'autres frameworks en ont" est exactement le genre de conversation que nous essayons d'éviter, en fait - car cela conduit à une conception qui est par définition optimisée pour les besoins des autres frameworks. Il est très utile dans le processus de décrire le problème que nous essayons de résoudre dans le contexte de Flutter, car cela nous aide tous à nous mettre d'accord sur le fait que le problème est le même ou non, si la solution doit être la même, etc.

@rrousselGit - bien sûr, il y a des conversations générales utiles que nous pourrions avoir avec l'équipe React. Je salue l'offre, et peut-être devrions-nous le faire à un moment donné. Ils ont beaucoup d'intelligence dans cette équipe, c'est sûr, et leur offre est très aimable et gentille. En ce moment, nous parlerions principalement avec eux parce que vous nous l'avez dit, plutôt que parce que nous avons des questions spécifiques dont nous sommes suffisamment informés pour en discuter :)

Et aussi, juste un rappel : "l'équipe Flutter" est juste les personnes qui contribuent à Flutter. Certains contributeurs travaillent pour Google, et certains contributeurs jouent un rôle plus important dans la gouvernance de l'architecture du projet, mais vous faites également partie de l'équipe Flutter, comme toute autre personne qui contribue au projet :)

Comme toujours - merci - pour votre patience à en discuter, pour vos contributions à la communauté, pour continuer à faire avancer le projet avec des idées créatives dans cet espace !

Pour clarifier, "bug" tel que nous l'utilisons est un terme général qui fait référence à tout ce qui pourrait conduire à un changement. Cela peut être un cas d'utilisation, une idée, une erreur de logique, une faute de frappe dans la documentation, quelque chose de déroutant sur le site Web, peu importe.

Peut-être pouvons-nous montrer des exemples complets d'applications qui ont de tels problèmes qui seraient résolus avec des crochets. Nous ne les réécrirons pas nécessairement avec des crochets, mais montrerons simplement combien il y a de copier-coller.

@satvikpendem Si le problème est "mon application a trop de passe-partout", alors c'est certainement un bogue que vous devriez signaler et nous pouvons discuter de la façon d'améliorer les choses. Mentionnez le bogue # ici afin que nous sachions continuer la conversation dans votre bogue.

Merci pour le commentaire @Hixie. Mon problème est largement couvert par le même bogue que @rrousselGit a mentionné (# 51752) donc je ne pense pas avoir plus à ajouter en fonction de ce que j'ai lu dans ce numéro.

@timsneath Je ne suis pas sûr de comprendre votre commentaire à @lukepighetti , car dans, on dirait que nous avons décrit le problème dans le contexte de Flutter à plusieurs reprises, comme ce numéro, # 51752, et d'autres. Que devrions-nous inclure d'autre ? Comment pourrions-nous vous aider à être mieux informé sur cet espace problématique, de sorte que si nous parlions à l'équipe React ou à d'autres, vous auriez suffisamment de connaissances pour poser des questions éclairées, comme vous le dites ?

Je suis d'accord que nous ne devrions pas copier des éléments d'autres frameworks simplement parce que React les a, par exemple, il pourrait donc être utile de voir d'autres solutions à ce problème de duplication de code. Le fondateur de Vue @yyx990803 a posté certaines de ses réflexions dans le RFC de Vue (https://www.github.com/vuejs/rfcs/tree/function-apis/active-rfcs%2F0000-function-api.md) ce qui serait utile passer par. Un regard particulier sur les sections sur les problèmes résolus et pourquoi ils sont respectueusement en désaccord sur l'API basée sur les classes est utile à lire.

Merci d'avoir clarifié @Hixie , j'ai mal compris cette définition plus large (peut-être interne?) De "bogue".

@timsneath Je ne suis pas sûr de suivre. Un autre groupe de personnes, les développeurs de réaction de base, ont déjà identifié et communiqué un ensemble de problèmes, créé une solution dans un cadre architecturalement similaire, et de nombreuses équipes frontales à travers plusieurs cadres signalent le succès. Je ne vois aucune indication qu'il s'agit d'un problème GitHub "solution avant problème". Il semble que @Hixie ne soit pas d'accord qu'il y ait un problème à résoudre, et il semble que cela soit basé sur des choix stylistiques ou de maintenance qui ne reflètent pas les avantages de l'expérience du développeur. Je dis cela avec le plus grand respect tout en essayant de comprendre d'où vient la réticence à ce RFC.

Je ne recommande normalement pas les fonctionnalités de perroquet, mais la RFC pour les crochets n'est pas sans art antérieur avec une bonne justification. L'art antérieur est disponible auprès de l'équipe de réaction principale, et toute justification que nous proposerons répétera ce qu'ils peuvent et ont communiqué. @rrousselGit semble vous recommander d'organiser une réunion avec eux pour discuter de ce sujet, car ils peuvent fournir beaucoup plus d'informations que nous ne le pouvons dans un problème GitHub.

En tant que méta-problème, pour moi personnellement, il serait utile qu'il y ait un processus concret pour intégrer de larges RFC dans la feuille de route flutter/flutter qui sont présentées par la communauté. Nous avons un dicton selon lequel les intervenants externes sont ceux qui veulent le travail difficile et nécessaire, c'est pourquoi ils doivent être inclus et pris au sérieux. Externe dans le contexte de flutter/flutter serait non-équipe, non-google, non-GDE.

J'ai documenté notre processus RFC sur notre wiki.

Externe dans le contexte de flottement/flutter serait non-équipe, non-google, non-GDE.

Par définition, si vous soumettez un RFC, vous êtes un membre de l'équipe.

Mon problème est largement couvert par le même bogue que @rrousselGit a mentionné (#51752)

Dans ce cas, je recommande de participer à cette discussion ; ce problème particulier est clos mais celui-là est ouvert. Il y a eu quelques descriptions de propositions dans ce numéro, bien qu'aucune ne semble faire du bon travail. Il n'y a pas encore eu de description particulièrement claire des "crochets" là-bas, cela n'a été mentionné qu'en passant.

Je ne comprends toujours pas pourquoi nous sommes censés expliquer le problème alors que les problèmes et les solutions proposées sont très clairement documentés par React et Vue.

Le RFC de hooks contient environ 1400 commentaires, vidéos d'introduction, documentations et articles de nombreuses personnes intelligentes.

Nous pouvons être en désaccord sur la solution à ces problèmes. Mais il ne devrait pas être nécessaire d'expliquer les problèmes

Le problème a été expliqué dans #51752, n'est-ce pas ? N'est-ce pas le problème?

(Pourquoi : parce que diriger une équipe de développement vers un RFC de 1400 commentaires pour un produit différent n'est pas un moyen efficace de communiquer avec cette équipe de développement. Je suis désolé si j'ai l'impression d'être obtus.)

Désolé de cingler le megathread. Je voulais juste dire à tous ceux qui ont suivi celui-ci que j'ai laissé quelques réflexions supplémentaires du point de vue de React dans https://github.com/flutter/flutter/issues/51752#issuecomment -665380355 et que je serais heureux de répondre plus de questions si cela peut être utile.

Je voulais également exprimer l'espoir que cela (et les fils de discussion associés) puisse rester civil et ne pas faire pression sur les responsables avec des arguments tels que "ça marche pour React". React et Flutter ont des différences significatives dans le modèle de programmation, et React Hooks s'appuie spécifiquement assez fortement sur certaines de nos nuances. Ils ont également des bizarreries que beaucoup pourraient ne pas accepter.

J'ai changé d'avis sur les crochets. Je pense qu'ils sont un modèle fantastique, mais je viens de terminer un contrat React Native et les crochets ont (à mon avis) fragmenté horriblement le système de développement pour très peu de gain. Flutter utilise actuellement un modèle très similaire aux composants de la classe React et il existe une tonne d'outils construits autour de lui. Si le framework devait passer aux hooks comme principale solution de gestion d'état, cela briserait tout le travail et les schémas mentaux existants que les développeurs Flutter utilisent pour très peu de gain.

Je pense qu'il existe un argument selon lequel les crochets sont un modèle supérieur pour le développement productif, mais je pense qu'il existe un argument plus convaincant (comme l'argument de base de dartfmt) selon lequel la cohérence dans le temps est meilleure que "meilleure".

Je dois également noter que lorsque nous traitons avec de nouveaux développeurs React, nous rencontrons souvent des obstacles avec des crochets créant des résultats inattendus et devons d'abord leur apprendre à utiliser des composants de classe. (Une bonne comparaison est le phénomène selon lequel les nouveaux développeurs ont plus de facilité à utiliser les boucles for par rapport aux méthodes de collecte telles que map/reduce/filter/fold). Les crochets sont un modèle avancé et nous tenons parfois cela pour acquis. La chose frustrante ici est que la communauté React supprime rapidement la documentation et la prise en charge des modèles de composants de classe, ce qui rend plus difficile d'offrir cette formation ou cette option aux nouveaux développeurs.

J'avais mentionné dans l'autre numéro # 51752 que nous devrions peut-être travailler à la création d'une version plus spécifique de Flutter des crochets, car les crochets eux-mêmes semblent avoir des inconvénients tels que le modèle useEffect(() => ..., [] ) pour un rendu unique. @Hixie a fait une version intéressante avec le modèle Property et PropertyManager qui semble faire quelque chose de similaire aux crochets mais peut ne pas avoir ces inconvénients. Nous devrions examiner davantage les alternatives aux crochets car, au moins pour Flutter, on a l'impression qu'il y a quelque chose qui fonctionne mieux que les crochets de style React mais qui résout toujours les mêmes problèmes.

Cette page vous a été utile?
0 / 5 - 0 notes