Flutter: Widget-Hooks

Erstellt am 12. Dez. 2018  ·  100Kommentare  ·  Quelle: flutter/flutter

Das React-Team hat kürzlich Hooks angekündigt: https://medium.com/@dan_abramov/making -sense-of-react-hooks-fdbde8803889. Aufgrund der Ähnlichkeit von Flutter mit React wäre es wahrscheinlich interessant zu sehen, ob diese auch zu Flutter passen.

Die Definition:

Hooks sind den State von StatefulWidget sehr ähnlich, mit einem Hauptunterschied: Wir können so viele Hooks auf einem Widget haben, wie wir möchten.
Hooks haben Zugriff auf alle Lebenszyklen, die ein State (oder eine modifizierte Version) hat.

Hooks können für jedes beliebige Widget verwendet werden. Im Gegensatz zu State , das nur für einen bestimmten Widget-Typ verwendet werden kann.

Hooks unterscheiden sich von Super-Mixins, da sie keine Konflikte erzeugen können. Hooks sind _völlig_ unabhängig und haben nichts mit dem Widget zu tun.
Dies bedeutet, dass ein Hook verwendet werden kann, um Werte zu speichern und öffentlich zugänglich zu machen, ohne Konflikte befürchten zu müssen. Es bedeutet auch, dass wir im Gegensatz zu Mixins denselben Hook mehrmals wiederverwenden können.

Das Prinzip:

Hooks werden grundsätzlich innerhalb von Element in einem Array gespeichert. Sie sind nur über die Methode build eines Widgets zugänglich. Auf Hooks sollte bedingungslos zugegriffen werden, Beispiel:

TUN:

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

NICHT:

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

Diese Einschränkung mag sehr einschränkend erscheinen, liegt aber daran, dass Hooks nach ihrem Index gespeichert werden. Nicht ihren Typ oder Namen.
Dadurch kann derselbe Haken so oft wie gewünscht wiederverwendet werden, ohne dass eine Kollision auftritt.

Der Anwendungsfall

Der nützlichste Teil von Hooks ist, dass sie es ermöglichen, die Lebenszykluslogik in eine wiederverwendbare Komponente zu extrahieren.

Ein typisches Problem mit Flutter-Widgets sind Wegwerfobjekte wie AnimationController .
Sie erfordern normalerweise sowohl eine initState - als auch eine dispose -Überschreibung. Kann aber gleichzeitig aus Wartbarkeitsgründen nicht in ein Mixin extrahiert werden.

Dies führt zu einem gemeinsamen Code-Snipper: 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 löst dieses Problem, indem es die Lebenszykluslogik extrahiert. Dies führt zu einem potenziell _viel_ kleineren Code:

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

    );
  }
}

Eine naive Implementierung eines solchen Hooks könnte die folgende Funktion sein:

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 ist einer dieser "Hook".

Wobei eine naive Implementierung eines solchen Hakens die folgende wäre:

Dieser Code sollte ähnlich aussehen wie jemand, der an die Klasse State gewöhnt ist. Aber das hat ein paar interessante Punkte:

  • Der Hook kümmert sich vollständig um die AnimationController , von der Erstellung bis zur Entsorgung. Aber auch Updates.
  • Es kann leicht in eine wiederverwendbare Verpackung extrahiert werden
  • Es kümmert sich auch um die Aktualisierung von duration beim Hot-Reload, anstatt ein AnimationController in initState zu erstellen.
  • Hooks können andere Hooks verwenden, um eine komplexere Logik zu erstellen

Nachteile

Haken sind mit Kosten verbunden. Der Zugriff auf einen Wert hat einen ähnlichen Overhead wie ein InheritedElement . Und sie erfordern auch, einen neuen Satz von kurzlebigen Objekten wie Verschlüssen oder "Widgets" zu erstellen.

Ich muss noch einen Benchmark durchführen, um den wirklichen Unterschied zu sehen


Ein weiteres Problem betrifft das Hot-Reload.

Hinzufügen von Haken am Ende der Liste, wenn in Ordnung. Da Hooks jedoch auf der Grundlage ihrer Reihenfolge funktionieren, führt das Hinzufügen von Hooks in der Mitte vorhandener Hooks zu einem teilweisen Zurücksetzen des Status. Beispiel:

Wenn Sie von A, B zu A, C, B wechseln, wird der Status von B zurückgesetzt (wobei sowohl dispose als auch initHook erneut aufgerufen werden).

Fazit

Hooks vereinfacht _viel_ die Welt der Widgets, indem es eine größere Code-Wiederverwendung ermöglicht. Besonders auf die sehr verbreiteten Szenarien wie Dispose, Memoize und Watching a value.

Sie können verwendet werden, um ein StatefulWidget vollständig zu ersetzen.

Aber sie erfordern ein Umdenken, und das teilweise Zurücksetzen des Zustands beim Refactoring kann lästig sein.

Es ist möglich, Hooks außerhalb von Flutter zu extrahieren, indem Sie benutzerdefinierte Elemente erstellen. Es besteht keine Notwendigkeit, die Quellen ab sofort zu ändern.

Aber aufgrund der Besonderheit von Hooks würde es _sehr_ von einem benutzerdefinierten Linter profitieren. Welche externen Pakete derzeit nicht bereitstellen können.

Bonus

~Eine Work-in-Progress-Implementierung ist hier verfügbar: https://github.com/rrousselGit/flutter_hooks (neueste Funktionen befinden sich im prod-ready -Zweig).~

~Ein Release ist bald als Alpha geplant. Aber die aktuelle Implementierung funktioniert teilweise.~

Verfügbar hier https://pub.dartlang.org/packages/flutter_hooks# -readme-tab-

framework new feature

Hilfreichster Kommentar

Ich wollte nur sagen – wenn jemand aus dem Flutter-Team 1:1 über Hooks plaudern möchte, erkläre ich gerne den historischen und technischen Kontext, warum wir sie in React übernehmen. Dieser Kommentar könnte auch interessant sein: https://github.com/reactjs/rfcs/pull/68#issuecomment -439314884.

Alle 100 Kommentare

@Hixie @eseidelGoogle

Hier ist ein Follow-up zu https://twitter.com/ericmander/status/1070024779015479302 mit einigen Details darüber, was ich im Sinn hatte. Nur für den Fall, dass das Flutter-Team weiter in das Thema investieren möchte

Hi @rrousselGit, ich habe mir neulich dein flatter_hooks-Paket angesehen. Ich bin mir nicht sicher, welche Optionen wir haben, um sie in Flutter zu implementieren, aber ich habe bemerkt, dass Sie Hook-Methoden über HookContext übergeben, während Hooks in React separat erstellt und als eine Art „State Mixin“ verwendet werden können. Der Hauptunterschied besteht darin, dass flutter_hooks zu verlangen scheint, dass alle Hook-Methoden in das Paket eingebaut werden, während React Hook-Methoden völlig getrennt zulässt.

Es scheint, als wäre dies für die Übereinstimmung mit der React-Spezifikation von entscheidender Bedeutung. Haben Sie eine Idee, wie dies erreicht werden könnte?

BEARBEITEN :

HookContext wurde entfernt und alle Hooks sind jetzt statische Methoden. Also das Folgende ist jetzt veraltet


Mein Paket tut dies für die automatische Vervollständigung, aber es ist keine Notwendigkeit.

Anstatt

context.useSomeHook()

Wir können haben

useSomeHook(context)

Dies ändert streng genommen nichts außer der Auffindbarkeit.

Das Hauptmerkmal ist

T HookContext.use<T>(Hook);

Damit können Sie von dort aus Ihre eigenen Haken bauen. Solange wir diese Methode haben, können wir alles tun, was React tut.

Aber aufgrund der Besonderheit von Haken würde es sehr von einem benutzerdefinierten Linter profitieren. Welche externen Pakete derzeit nicht bereitstellen können.

Ich würde empfehlen, dass Sie positiv abstimmen (und Ihren Anwendungsfall hinzufügen)
https://github.com/dart-lang/linter/issues/697. Es wäre großartig, wenn Pakete ihre eigenen benutzerdefinierten Fusseln bereitstellen könnten.

Ein weiteres Problem betrifft das Hot-Reload.

Dieser macht mir Sorgen. Es wäre traurig, wenn wir das Hot-Reload-Erlebnis verschlechtern würden.

Verfügbar hier https://pub.dartlang.org/packages/flutter_hooks

Können Sie erläutern, welche Vorteile es hat, dies in das Flutter-Framework zu integrieren, anstatt nur ein externes Paket zu haben?

Über Hot Reload habe ich es integriert und es ist reibungslos zu bedienen.

Das einzige wirkliche Problem ist #26503, für dessen Behebung anscheinend eine Änderung der Werkzeuge erforderlich ist. Und ich habe nicht die Bandbreite dafür.


Es gibt mehrere kleine Verbesserungen, die wir an Hooks bringen können, indem wir sie in Flutter integrieren:

  • Etwas Leistungssteigerung, da nicht von StatefulElement abhängig
  • Refactoring/Analyse, was derzeit mit analyzer_plugin nicht oder nur sehr eingeschränkt möglich ist

Aber ich denke, der Hauptgrund ist: Hooks sind Teil einer größeren Arbeit an React, also asynchronem Rendering.

Wenn Flutter jemals auf die Async-Rendering-Route gehen möchte (und das sollte es auch), sind zwei Dinge erforderlich:

  • Mehrere Rahmenänderungen
  • Etwas Ähnliches wie Haken

Hinzu kommt der offensichtliche Community-Aspekt. Mit 270 Sternen in einem Monat und einem Platz auf https://github.com/trending/dart?since=monthly , ohne dass ich sie wirklich beworben hätte – Hooks sind definitiv etwas, das das Interesse der Community weckt.

Das Ziel von Hooks ist es, die Syntax von Widgets so zu ändern, dass Menschen lebenszyklusspezifische Logik für Pub freigeben können.

Da Hooks offiziell unterstützt werden, würde dies die Bemühungen der Community exponentiell erhöhen.

Neugierig: Können Sie erklären, wie Sie es für Hot Reload zum Laufen gebracht haben?

Ich habe StatefulElement anstelle von ComponentElement erweitert, sodass ich Zugriff auf reassemble habe.
Dadurch kann der nächste build -Aufruf die Hook-Liste ändern, während der normale Neuaufbau daran gehindert wird.

Grundsätzlich gilt: Wenn previousHook.runtimeType != newHook.runtimeType an einem gegebenen Index steht, werden dieser Hook und alle folgenden verworfen.

Der "all the following"-Teil liegt daran, dass ein Hook andere Hooks verwenden kann; Es reicht also nicht, nur einen zu entfernen.
Ab einem Monat konstanter Nutzung ist es selten ein Problem.

Es ist eigentlich das Gegenteil, das Hot-Reload-Erlebnis scheint verbessert zu sein. Da sich alles innerhalb der Methode build befindet, wendet ein Hot-Reload immer die Änderungen an (im Gegensatz zu einem initState ). Ein typisches Beispiel ist AnimationController :

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

Dieser Haken ermöglicht ein reibungsloses Hot-Reload der Dauer; was normalerweise einen Hot-Restart erfordert.

Ich habe angefangen, einen Teil meiner Haupt-App zu übersetzen, um einige Boilerplates zu entfernen. Ich sehe Hooks nicht als Feature, sondern als vollständiges Muster. Es gibt viele Themen, die nur darauf warten, umgesetzt zu werden, und die der Produktivität, aber auch der Wartung sehr zugute kommen würden. Ich begann mit Animationen, entfernte Controller und würde gerne Hooks für Firebase oder andere gängige Fälle sehen.

Es ist eigentlich das Gegenteil, das Hot-Reload-Erlebnis scheint verbessert zu sein. Da sich alles innerhalb der Build-Methode befindet, wendet ein Hot-Reload die Änderungen immer an (im Gegensatz zu einem initState).

👍 Diese Erkenntnis traf mich auch ein paar Wochen, nachdem ich Sebastians Antrag zum ersten Mal gesehen hatte.

Der "all the following"-Teil liegt daran, dass ein Hook andere Hooks verwenden kann; Es reicht also nicht, nur einen zu entfernen.

Ich dachte auch, dass in JS vielleicht eine Heuristik hilfreich sein könnte: Wenn ein heißes Neuladen dazu führt, dass render (Flutters build ) wirft (z. B. aufgrund nicht übereinstimmender Typen), setzen wir alle Hooks zurück und versuchen es erneut. Wenn es wieder scheitert, dann scheitern wir.

Ich nehme an, Sie haben dieses Problem nicht, weil Sie zu stark tippen? Ich bin mir nicht sicher. Was passiert, wenn Sie die Bearbeitung mit einem String State Hook beginnen und dann den Code ändern, um anzunehmen, dass es sich um eine Zahl handelt?

Was passiert, wenn Sie die Bearbeitung mit einem String State Hook beginnen und dann den Code ändern, um anzunehmen, dass es sich um eine Zahl handelt?

Du meinst von:

final counter = useState(0)

zu:

final name = useState('foo');

?

Wenn dies der Fall ist, erkennt das Schreibsystem korrekt, dass sich der Typ geändert hat. Dies liegt daran, dass der Typ useState tatsächlich useState<int> im Vergleich zu useState<String> ist.

JS wird es hier wahrscheinlich schwerer haben.

Ich verstehe nicht wirklich, was dir das erspart. Eine leicht verständliche Deklaration, eine leicht verständliche Zeile im initState und eine leicht verständliche Zeile im Dispose werden durch eine weniger effiziente und vollständig undurchsichtige Zeile in der Build-Methode ersetzt (wobei performance kritisch). Das scheint kein gutes Geschäft zu sein. Können Sie die Vorteile hier näher erläutern?

(Das heißt, https://pub.dartlang.org/packages/flutter_hooks scheint hier bereits alles zu implementieren, also schätze ich, dass wir der Plattform nichts hinzufügen müssen?)

Haken sind eine Lösung für ein Problem, mit dem React seit Jahren konfrontiert ist. Und da Flutter sich viel von React inspirieren lässt, hat es auch diese Probleme importiert.

Ich bin ziemlich schlecht im Marketing, also würde ich dringend empfehlen, sich den Vortrag des React Teams darüber anzuschauen. Ihre Einführung beginnt hier https://youtu.be/dpw9EHDh2bM.

Gefolgt von einem direkten Vorher/Nachher-Vergleich von Dan Abramov (der hier ein paar Kommentare oben beantwortete).

Der Punkt ist, dass alles, was sie in diesem Gespräch halten, auch für Flutter gilt (einschließlich ihres Blogs über Mixins, die schädlich sind https://reactjs.org/blog/2016/07/13/mixins-considered-harmful.html)


Hooks lassen sich jedoch in dem folgenden eingängigen Satz zusammenfassen:

Mit Hooks können Sie einen noch größeren Prozentsatz Ihrer Anwendung "veröffentlichen".

Dies liegt daran, dass Hooks vollständig aus dem Widget extrahiert und für andere zur Verwendung im Pub veröffentlicht werden können. Das ist derzeit mit StatefulWidget unmöglich, da unsere Logik an State Lebenszyklen gebunden ist.

Ein weiterer Effekt von Hooks ist, dass es die Gruppierung des Codes ändert. Aktuell haben wir folgendes:

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();
}

Alles wird gemischt und über mehrere Lebenszyklen verteilt. Es wird sehr schwierig zu erkennen, ob wir vergessen haben, eine Variable zu löschen/aktualisieren.

Mit Hooks wird es wie folgt:

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]);

Jetzt ist alles neu gruppiert. Es wird viel offensichtlicher, ob wir vergessen haben, eine Variable zu löschen/aktualisieren oder nicht, und wir können diese Logik leicht in eine statische Funktion extrahieren, die alles intern erledigt.

Haken entsprechen DRY. Wir schreiben einmal die Logik zum Erstellen/Aktualisieren/Entsorgen einer Variablen. Und wir verwenden es überall wieder, anstatt es zu kopieren und einzufügen.

Ein visuelles Beispiel (in React):


Insgesamt ist es zwar unglaublich, dass es möglich ist, Hooks außerhalb des Flutter-Repositorys zu implementieren; Ich denke nicht, dass es so bleiben sollte, wie es ist.

Es ist, als ob Flutter nur die Basisklasse Widget bereitstellt und StatefulWidget als externe Abhängigkeit erstellt: Es ergibt keinen Sinn.

Flutter ist ein Framework, wir wollen nicht nur die Basics anbieten

Das heißt, wir wollen auch:

  • Stellen Sie Hooks für alle Framework-Aspekte bereit, die davon profitieren würden
  • mit dem Widget-Inspektor interagieren (die aktuelle Benutzeroberfläche ist nicht für einen solchen Anwendungsfall optimiert)
  • Refactoring/Linter
  • Bereitstellung von Testdienstprogrammen

Dies erfordert einen enormen Arbeitsaufwand und kann mehrere PR in Flutter erfordern.
Es ist sehr weit vom Umfang eines kleinen Pakets entfernt, das von einem Mann in seiner Freizeit gepflegt wird.

Hooks sind DRY und sind Geschäftslogik-/Status-Mixins, die eine saubere Kolokation von Code fördern. Die Alternative ist die fragmentierte Wiederholung über eine Codebasis.

Ich stimme zwar zu, dass es auf dem Papier undurchsichtiger ist, aber das Muster ist wiederholbar und verständlich, sodass es nach einem Tag des Gebrauchs transparent wird. Es ist wie jedes andere Programmiermuster: undurchsichtig, wenn Sie beginnen, transparent, wenn Sie es verwenden, aber mit Hooks ist der Übergang fast augenblicklich.

Im Gegenzug denken viele Entwickler, dass Hooks viele Fälle überflüssig machen, die ursprünglich auf Klassenkomponenten angewiesen waren. Daher würde in naher Zukunft die funktionale Komponente in den Mittelpunkt rücken.

Meine naive Frage ist, ob es auch sinnvoll ist, funktionale Widgets in Flattern zu unterstützen. Ich verstehe, dass das derzeit funktionierende Widget nicht empfohlen wird, da es nicht mit seinem eigenen Element verknüpft ist und kein eigener BuildContext vorhanden ist. Wäre es vorteilhaft, einen neuen Funktionsmechanismus einzuführen, der die gleichen darunterliegenden Objekte erstellen kann wie das Klassen-Widget?

@ivenxu Das habe ich auch in einem anderen Paket erstellt: https://github.com/rrousselGit/functional_widget

Es ist ein Codegenerator, der eine Klasse aus einer Funktion generiert (mit Schlüsseln und allem) und mit Hooks kompatibel ist, um ein HookWidget zu generieren

Die Summe aus beiden ist:

<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());
}

Es macht einen schönen Text, der progressiv von 0 bis 1 geht.
In 6 Zeilen Code ...
Was mit üblichen Widgets mehr als 30 Zeilen erfordern würde.

Und ich zähle nicht die automatisch generierten debugFillProperties und operator== Überschreibungen.

@rrousselGit Ich war mir Ihrer Arbeit an funktionalen Widgets bewusst, gute Sachen und danke! Ich spreche jedoch von nativer Unterstützung durch Flutter.

Übrigens, wie läuft das angehängte Debugging für die Code-Generierung? Ist das möglich, einen Haltepunkt in foo() zu setzen und die lokale Variable zu untersuchen? Wie sieht der Callstack aus?

Manchmal ist das funktionale Paradigma für Komponenten/Widgets viel prägnanter als das Klassengegenstück. Ich suche also nach Ideen, ob nativ unterstützte funktionale Widgets einen Unterschied machen würden.

Mit Hooks wird es zu folgendem

Ich denke wirklich, dass das „Vorher“-Bild hier viel klarer und leichter zu verstehen ist als das „Nachher“-Bild. Das ist aber natürlich eine subjektive Meinung.

Es ist, als ob Flutter nur die Widget-Basisklasse bereitstellt und StatefulWidget als externe Abhängigkeit erstellt: Es ergibt keinen Sinn.

Das würde tatsächlich sehr gut mit Flutters Layering-Philosophie übereinstimmen. Der Hauptgrund, warum wir StatefulWidget als erstklassigen Kernbestandteil der Widgets-Schicht im Framework haben, ist, dass andere Features im Framework davon abhängen (z. B. GlobalKey ), also können wir das nicht. Aber so oft wie möglich extrahieren wir Features, damit sie nicht im Kern sind.

Ich denke, es macht sehr viel Sinn, dies als Paket für diejenigen zu haben, die es verwenden möchten. Wenn wir irgendetwas im Core Framework tun können, um die Implementierung besser, effizienter usw. zu machen, dann sollten wir das auf jeden Fall tun.

Ich finde das ist ein tolles Projekt und verfolge das Paket mit Interesse.

Allerdings ist mir nicht ganz klar, warum dies im Rahmen sein sollte. Dies scheint ein sehr nützliches Muster zu sein, das manche Leute lieben werden und andere es vorziehen, es nicht zu verwenden.

@rrousselGit Ich vermute, Sie hätten viel Erfolg, Kernframework eröffnen würden, die dazu beitragen würden, dass es erfolgreicher wird. Wenn es etwas gibt, das Sie im Framework verfügbar machen müssen, das derzeit nicht funktioniert, lassen Sie es uns angehen. Wenn es einen Fehler im Framework gibt, der dies blockiert, lassen Sie es uns zum Laufen bringen!

Und FWIW, ich sage das, nachdem ich eine ähnliche Erfahrung mit flutter_svg gemacht habe - was zu einigen Beiträgen zum Framework geführt hat und als Paket für viele Leute nützlich sein konnte.

Ich habe gerade festgestellt:
Wenn Hooks in Flutter implementiert sind, ist ComponentElement ein guter Kandidat.

Das bedeutet, dass anstelle eines neuen Widget-Typs sowohl StatelessWidget als auch StatefulWidget mit Hooks kompatibel wären.

Dieser Ansatz könnte eine Koexistenz beider Syntaxen ermöglichen. Dies könnte nützlich sein, wenn man bedenkt, dass beide Syntaxen ihre Vor- und Nachteile haben


Mir geht es vorerst gut damit, dass Hooks außerhalb von Flutter sind.

Meine einzige Sorge ist, dass dies die Verwendung von Hooks insgesamt reduzieren wird, da es inoffiziell ist. Reduzieren Sie daher die Anzahl der auf Pub verfügbaren Hooks.

Wenn man bedenkt, dass der größte Vorteil von Hooks der Einfluss auf die Community ist (benutzerdefinierte Hooks, die im Pub veröffentlicht werden können), schadet dies ihrer Nützlichkeit.

Ich wollte nur sagen – wenn jemand aus dem Flutter-Team 1:1 über Hooks plaudern möchte, erkläre ich gerne den historischen und technischen Kontext, warum wir sie in React übernehmen. Dieser Kommentar könnte auch interessant sein: https://github.com/reactjs/rfcs/pull/68#issuecomment -439314884.

@Hixie oder @dnfield hat sich jemals jemand von euch an @gaearon gewandt?

Als Flutter-Benutzer, der React auch häufig verwendet, kann ich sagen, dass Hooks ein echter Game Changer für React waren. Ich schreibe meinen gesamten neuen Code ausschließlich mit Hooks und portiere alle alten Klassen auf Hooks, während ich an ihnen arbeite. Die Vorteile, den gesamten Code, der sich auf einen bestimmten Teil Ihrer Komponente bezieht, am selben Ort zu haben, sind erstaunlich!

Ich denke, es wäre großartig, wenn man sich bemühen würde, zu bewerten, ob dieses Paradigma zu Flutter passt oder nicht ❤️

Diesen Kommentar hatte ich übersehen! Ich habe mich einfach an sie gewandt.

Ich muss zugeben, dass ich nicht wirklich verstehe, wie sich Hooks auf Flutter bezieht. Es gibt bereits einige Hooks-Pakete, wenn Sie damit experimentieren möchten (einige werden in diesem Fehler oben erwähnt). Grundsätzlich verstehe ich nicht wirklich, welches Problem das Konzept löst.

Weitere Details zu meiner Perspektive finden Sie hier in meinen früheren Kommentaren: 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.

Grundsätzlich verstehe ich nicht wirklich, welches Problem das Konzept löst.

Hooks sind wie Status-Mixins, aber ohne die inhärenten Probleme von Mixins: kein Variablenkonflikt und können mehr als einmal verwendet werden.

Hooks können eines der größten Probleme lösen, das Flutter im Moment mit zustandsbehafteten Widgets hat: den Umgang mit all diesen Controllern.

Jeder Controller benötigt sowohl einen initState, didUpdateWidget und dispose, die _immer_ gleich implementiert werden.

Wir können es nicht in eine Basisklasse/ein Mixin extrahieren, da wir möglicherweise mehr als eine benötigen.
Stattdessen müssen wir die Logik überall kopieren und einfügen.
Aber das ist auch nicht sehr gut. Es ist leicht, einen Schritt zu vergessen, wie das Überschreiben dispose .


Das eigentliche Problem mit Hooks ist, dass ihre Implementierung viel Arbeit erfordert.

Das Kerngerüst ist einfach. Aufgrund ihres einzigartigen Verhaltens erfordern sie jedoch eine tiefe Integration mit den Linter- und Refactoring-Tools.

Und für eine optimale Implementierung können einige Sprachfunktionen wie Tupple/Destrukturierung erforderlich sein.

Ich glaube nicht, dass dies wirklich die Kommentare anspricht, die ich oben hatte (https://github.com/flutter/flutter/issues/25280#issuecomment-455846788 und https://github.com/flutter/flutter/issues/25280# Ausgabekommentar-456272076 (insbesondere).

Hm, @gaearon wird es wahrscheinlich besser erklären als ich, aber aus meiner Sicht:

  • Das Lesbarkeitsargument hängt von der Größe des Widgets ab. Auf größeren Widgets neigen Hooks dazu, tatsächlich _besser_ lesbar zu sein, da alle zugehörigen Bits zusammen sind, anstatt über Lebenszyklen verteilt zu sein.

  • weniger Fehler. Ihre deklarative API macht es schwieriger zu vergessen, einen Zustand zu aktualisieren/bereinigen.

  • Über das „Warum sollten sie Kern sein?“ mag ich die von Dan Abramov verwendete Metapher.
    Haken sind für Widgets, was Elektronen für Atome sind.
    Es macht keinen Sinn, sie auszuschließen, wenn sie Primitive sind, die verwendet werden, um größere Dinge zu bauen.
    Es geht nicht nur darum, Hooks zu implementieren. Das gesamte Framework kann davon profitieren.
    Sie können verwendet werden, um Dinge wie Animationen, Formulare und vieles mehr zu verbessern.

@Hixie , haben Sie Zeit damit verbracht, Hooks zu verwenden, oder erstellen Sie eine Tabellenkalkulation, um eine Entscheidung zu treffen? Ich bin mir nicht sicher, wie viel Prozent der Zeit des Flutter-Teams damit verbracht wird, Framework-Sachen zu schreiben, im Vergleich zum Schreiben von Apps für Kunden. Ich vermute, dass Leute, die Apps für Kunden schreiben, diese Frage aus einem etwas anderen Blickwinkel angehen als ein Framework-Entwickler. Das heißt, wie macht mich das effektiver und bietet meinen Kunden mehr Wert, nicht wenn es die gleichen Kriterien wie eine bestehende Lösung erfüllt.

Ich habe flutter_hooks kürzlich zusammen mit Functional_widget in einer unserer neuen heißen Apps eingeführt.

Es reduzierte den Boilerplate-Code erheblich und nachdem all diese chaotischen Stateful-Widgets in winzige Funktionen mit Hooks umgestaltet worden waren, schrumpfte die Codebasis um etwa 70 %.

Aus einer höheren Sicht ist ein funktionales Widget mit einer Reihe von Hooks wie eine zwingende Vereinfachung der Kombination mehrerer Observables mit CombineLatest in RX. Aber anstatt alle Observables explizit in der Präambel anzugeben und eine Funktion darauf anzuwenden, sind Hooks viel flexibler, weil Sie sie dort in den Code einflechten, wo Sie den Wert benötigen.

Aber am Ende ist jedes dieser Widgets wie eine Stufe in einem RX-Stream.

Ich glaube nicht, dass wir flatter_hooks entfernen sollten. Ich sehe einfach nicht, was wir (das Flutter-Team) bieten können, das wertvoller ist.

Haken sind für Widgets, was Elektronen für Atome sind.

Ich denke, wenn wir dieser Metapher folgen, sollten Sie Flutter als Quarks oder vielleicht als Hadronen betrachten. Die Elektronen von Hooks sind eine Schicht darüber.

@Hixie , haben Sie Zeit damit verbracht, Hooks zu verwenden, oder erstellen Sie eine Tabellenkalkulation, um eine Entscheidung zu treffen? Ich bin mir nicht sicher, wie viel Prozent der Zeit des Flutter-Teams damit verbracht wird, Framework-Sachen zu schreiben, im Vergleich zum Schreiben von Apps für Kunden.

Ich habe Hooks selbst nicht verwendet. Ich schreibe Apps mit Flutter. Ich habe dabei keine Notwendigkeit für so etwas wie Hooks gefunden. Wie oben erwähnt, passt Hooks meiner Meinung nach nicht zu meinem Entwicklungsstil (ich ziehe es vor, die Boilerplate zu sehen). Ich möchte Hooks definitiv nicht von jemandem entfernen, der es verwenden möchte.

Ich sehe einfach nicht, was wir (das Flutter-Team) bieten können, das wertvoller ist.

Um Hooks wirklich nützlich zu machen, benötigen sie ein Analyse-Plugin und benutzerdefinierte Refactoring-Optionen.
Nur mit diesen glänzen Haken wirklich.

Hooks ermöglichen eine sehr starke statische Analyse, die mit einem typischen StatefulWidget unmöglich ist.
Dadurch wird die Verwaltung des lokalen Zustands eines Widgets sicherer/skalierbarer. Für mich ist die Reduzierung der Boilerplate nur ein Bonus.

Aber:

  • Es gibt _viel Arbeit_ auf APIs auf sehr niedriger Ebene.
  • Die Analysator-Plugin-Schnittstelle ist nicht stabil, fehlt, wird fast nicht verwendet und vom Team nicht empfohlen (da für jedes Plugin eine Analyse durchgeführt wird).
  • Flutter selbst verwendet die Plugin-API nicht und implementiert sie stattdessen direkt auf dem Server

Als von der Community gepflegtes Paket ist die Wahrscheinlichkeit, ein vollständiges Tooling für Hooks zu haben, sehr gering.

Ich denke, wenn wir dieser Metapher folgen, sollten Sie Flutter als Quarks oder vielleicht als Hadronen betrachten. Die Elektronen von Hooks sind eine Schicht darüber.

Wenn Flutter aus Quarks besteht, ist es auch eine Galaxie.

Wir haben tatsächlich sehr einfache Klassen wie Layer .
Aber es gibt auch eine riesige Menge an High-Level-Klassen wie Switch .

Die gesamten Material- und Cupertino-Bibliotheken könnten als Pakete, dann als Navigator und als verwandte Objekte extrahiert werden. Aber das sind sie nicht.
Und Hooks sind ein paar Schichten darunter.

Nicht verwandt, aber ich bin der festen Überzeugung, dass Material und Cupertino nicht in der Flutter-Kernbibliothek enthalten sein sollten, da dies einen Mangel an guten Schnittstellen fördert, die irgendwo zwischen Super-Low-Level- und Material-High-Level-Komponenten positioniert sind. Wenn Sie jemals versucht haben, eine App ohne Materialbibliothek zu erstellen, ist dies unglaublich schwierig.

Bei Hooks geht es nicht wirklich darum, Boilerplate zu reduzieren. (Wir haben auch nichts gegen Boilerplate.) Der primäre Wert besteht für mich darin, zustandsbehaftete Logik zu kapseln und zu komponieren.

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

In der Lage zu sein, Daten zwischen ihnen zu leiten, ohne sich Gedanken darüber zu machen, ob sie einen Status enthalten oder nicht, diese Logik in benutzerdefinierte Hooks zu extrahieren oder sogar denselben Hook mehrmals anzuwenden, ist sehr ausdrucksstark. Und im Gegensatz zu Rx-ähnlichen Ansätzen können Sie den gesamten Code tatsächlich schrittweise durchlaufen, ohne die Kombinatoren durchsuchen zu müssen.

Um Hooks wirklich nützlich zu machen, benötigen sie ein Analyse-Plugin und benutzerdefinierte Refactoring-Optionen.
Nur mit diesen glänzen Haken wirklich.

Ich stimme zu, dass wir dies unterstützen müssen. Das sollte jedoch ein Fehler sein, der gegen das Dart GitHub-Projekt eingereicht wurde. Ich möchte natürlich, dass wir Flutter-spezifische Lints aus der Dart-Codebasis entfernen.

Die gesamten Material- und Cupertino-Bibliotheken könnten als Pakete, dann als Navigator und als verwandte Objekte extrahiert werden. Aber das sind sie nicht.

Ja, das stimmt wohl auch. Es gibt praktische Gründe, warum wir das nicht tun (z. B. würde es das „Hello World“ verkomplizieren, was den Einstieg in Flutter erschweren würde), aber wir könnten es trotzdem in Betracht ziehen. Auch dies ist jedoch ein separates Problem, das wir separat einreichen sollten, wenn wir es berücksichtigen möchten.

Der primäre Wert besteht für mich darin, zustandsbehaftete Logik zu kapseln und zusammenzusetzen.

Das ist in der Tat sehr wertvoll. Es ist jedoch nicht klar, dass es im Core-Framework enthalten sein muss.

Das ist in der Tat sehr wertvoll. Es ist jedoch nicht klar, dass es im Core-Framework enthalten sein muss.

Dies würde es ermöglichen, einige Core-State-Mixins zu verwerfen.

Zum Beispiel ist AutomaticKeepAliveClientMixin in einer seltsamen Position.
Wir müssen super.build rufen, was sehr kontraintuitiv ist. Und das super.build gibt null zurück, was mit Nicht-Nullable-Typen nicht funktioniert.
Aber als Haken sind diese beiden Probleme gelöst.

Ebenso bräuchten wir nicht sowohl SingleTickerProviderStateMixin als auch TickerProviderStateMixin , da Hooks beliebig oft wiederverwendet werden können.

Alternativ haben Hooks einen wichtigen Community-Aspekt. Wenn sie nicht zum Kern gehören, ist es viel unwahrscheinlicher, dass Benutzer benutzerdefinierte Hooks erstellen und teilen.

Wir würden eigentlich keine Hooks im Core-Framework _benutzen_, da sie meiner Meinung nach die Dinge weniger lesbar machen. Sie im Kernframework zu haben, würde also nicht helfen, anderen Code zu entfernen.

Alternativ haben Hooks einen wichtigen Community-Aspekt. Wenn sie nicht zum Kern gehören, ist es viel unwahrscheinlicher, dass Benutzer benutzerdefinierte Hooks erstellen und teilen.

Wenn Hooks gut sind, werden die Leute sie verwenden, unabhängig davon, ob sie aus dem Flutter-Open-Source-Projekt oder dem, sagen wir, Hooks-Open-Source-Projekt stammen.

Wir würden eigentlich keine Hooks im Core-Framework _benutzen_, da sie meiner Meinung nach die Dinge weniger lesbar machen. Sie im Kernframework zu haben, würde also nicht helfen, anderen Code zu entfernen.

Alternativ haben Hooks einen wichtigen Community-Aspekt. Wenn sie nicht zum Kern gehören, ist es viel unwahrscheinlicher, dass Benutzer benutzerdefinierte Hooks erstellen und teilen.

Wenn Hooks gut sind, werden die Leute sie verwenden, unabhängig davon, ob sie aus dem Flutter-Open-Source-Projekt oder dem, sagen wir, Hooks-Open-Source-Projekt stammen.

Das klingt keine schlechte Idee. Hooks können als separates Open-Source-Projekt ausgeführt werden. Wird das Kernteam die Kernänderungsanforderung aus dem Hook-Projekt priorisieren? IMHO Es ist ziemlich wichtig für den Erfolg des Hook-Projekts.

Was ist die „Kernänderungsanforderung“?

Was ist die „Kernänderungsanforderung“?

Entwicklungstools.
Hauptsächlich über Analyse-Plug-Ins, aber möglicherweise auch über ein Plug-In-System für Flutter/Devtools.

Da steckt viel Arbeit drin, die die Community nicht leisten kann.

Wir würden eigentlich keine Hooks im Core-Framework _benutzen_, da sie meiner Meinung nach die Dinge weniger lesbar machen. Sie im Kernframework zu haben, würde also nicht helfen, anderen Code zu entfernen.

Bei allem Respekt, aber das klingt ein bisschen ignorant. Du solltest sie wirklich ausprobieren! Sie sind viel prägnanter, als mit initState/dispose/setState/build für jeden einzelnen Aspekt des Zustands herumzutanzen.

Bei Flutter dreht sich alles um Komposition und die Verwendung von Hooks folgt natürlich dem Kompositionsmuster, während die Verwendung von Mixins andererseits das Gegenteil von Komposition ist.

Ich nehme an, wir werden weiterhin erwägen, den Analysator erweiterbar zu machen, um eine hohe Priorität zu haben. Leider gibt es viele andere höhere Prioritäten, wie z. B. die Verbesserung der Erfahrung für grundlegende Aufgaben in der ersten Stunde und die Implementierung von Tools für die standardmäßige Nicht-Nullable-Änderung.

Das heißt, ich verstehe nicht, warum es nicht von Nicht-Googlern gemacht werden könnte. Flutter und Dart sind beide Open-Source-Projekte und viele Dinge werden von Nicht-Googlern implementiert.

Das heißt, ich verstehe nicht, warum es nicht von Nicht-Googlern gemacht werden könnte. Flutter und Dart sind beide Open-Source-Projekte und viele Dinge werden von Nicht-Googlern implementiert.

Wir sprechen von monatelanger Arbeit an mehreren Projekten für Dinge, die das Team als „Features mit niedriger Priorität“ betrachtet, mit vielen großen Breaking Changes. Und die betroffenen Projekte sind sehr niedrig und fast ohne öffentliche Dokumentation.

Der Investitionsaufwand und die Risiken der Absage / des Hängenbleibens sind viel zu hoch. Vor allem, wenn wir kein Geld dafür bekommen.

Obwohl ich Ihren Punkt verstehe, ist es äußerst unwahrscheinlich

Gibt es dazu einen Fahrplan? Haben Sie eine Ahnung, ob und wann es möglich sein könnte, dass Haken im Flattern landen?

Wenn Flutter erfolgreich ist (was ich hoffe), wird jeder React-Entwickler, der versucht, Flutter zu integrieren, in einem Jahr aufschreien, wenn er herausfindet, dass es hier keine erstklassige Unterstützung für Hooks gibt.

Das Flutter-Team hat eine gute Entscheidung getroffen, das klassenbasierte React-Modell zu kopieren, aber das gehört jetzt der Vergangenheit an, funktionale Komponenten und Hooks sind die Zukunft, das Flutter-Team sollte mit dieser neuen Realität aufwachen, wenn es auf Augenhöhe bleiben will .

Genau wie Cgarciae sagte, wird die React-Community in Zukunft auf Haken und funktionale Komponenten umsteigen. Und das lässt Flattern veraltet erscheinen, da das Programmiermodell und die Produktivität nicht mit anderen plattformübergreifenden Entwicklungslösungen mithalten würden.

Nachdem wir kürzlich sowohl Reagieren als auch Flattern ausprobiert haben, hinterlassen fehlende Haken im Flattern ein großes Loch in Bezug auf Produktivität, Konsistenz und Wartungsfreundlichkeit der verglichenen Wohnung. Es würde der Organisation nicht helfen, Flattern in ein neues Projekt einzuführen oder die Leute davon zu überzeugen, von der React-Basislösung zu Flattern zu wechseln, was den Aufwand wert ist.

Ich verstehe vollkommen, wenn jemand ein Toolset, eine Low-Level-Framework-Implementierung oder Boilerplate-Code erstellt, scheint dies kein großes Problem zu sein. Aber wenn ein App-Entwickler viele „unnötige“ Textbausteine ​​schreiben muss, um etwas zum Laufen zu bringen, ist der Effekt unerwünscht.

Abhängig davon, aus welchem ​​​​Blickwinkel die Leute auf ein bestimmtes Problem schauen, kann der Kompromiss / das Gleichgewicht anders aussehen. Das Fehlen geeigneter Tools oder bestimmter Funktionen kann dazu führen, dass die interne Implementierung des Frameworks sauberer aussieht, aber es entlastet nur die Verantwortung des Framework-Konsumenten und macht die clientseitige Implementierung komplizierter und ungeschickter, als es sein muss, was wiederum nicht zur Anpassung des Gebens beiträgt Rahmen. Für einen Anwendungsentwickler sind Produktivität und Konsistenz wichtig, ein einheitlicher Ansatz/Standard ist wichtig für Teamarbeit und Gemeinschaft. Ein ganzheitlicher Ansatz sollte immer die Menschen berücksichtigen, die auf der anderen Seite des Zauns leben.

Hooks sollten einfach zu implementieren sein, aber funktionale Widgets sind schwieriger. Das würde Union-Typen in Dart erfordern, da Sie etwas ausdrücken müssen wie:

'Widget | Widget-Funktion(BuildContext)'.

funktionale Widgets sind schwieriger. Das würde Union-Typen in Dart erfordern

Das ist bei weitem nicht genug.
Bleibt noch die Frage:

  • Wie übergebe ich Parameter an Funktionen? Curry?
  • Einmal in der Widget-Struktur sollten zwei funktionale Widgets einen unterschiedlichen runtimeType haben
  • Wie stecke ich Widgets mit devtools? (die debugFillProperties Methode von Widgets)

Ich habe lange darüber nachgedacht. Ich sehe keine einfache Lösung für funktionale Widgets.
Das einzige, was mir einfällt, ist eine Kombination aus Codegenerierungs- und Analyse-Plugins (um die richtige Go-to-Definition und so weiter zu haben).

Tatsächlich hat uns der Teil der Codegenerierung dazu gebracht, aus Ihrem Functional_Widget-Paket auszusteigen. Es erzeugt einfach zu viele Sprünge beim Überprüfen von Code. Also für mich würde das nicht fliegen...

Es erzeugt einfach zu viele Sprünge beim Überprüfen von Code

Deshalb habe ich ein Analyse-Plugin erwähnt.

Mit einem benutzerdefinierten Analyse-Plugin sollten wir in der Lage sein:

  • Stellen Sie sicher, dass die Funktion nicht direkt verwendet wird und die Klasse bevorzugt wird
  • ein richtiges "go to definition"/"peek"/... haben, so dass ein Klick auf die Klasse zur Funktion umleitet

Dies sollte alle Probleme beheben.
Aber wir gehen zurück zu den "Hooks brauchen ein richtiges Analyser-Plugin-System".

Vielleicht ist die Einführung functional -Widgets nicht notwendig:

Nehmen wir an, die Verwendung von Hooks ist nur innerhalb der Methode StatelessWidget build erlaubt.

Aus technischer Sicht - es spielt keine Rolle (soweit ich mich jetzt erinnern kann), ob es Klasse oder Funktion ist. Der wichtige Teil ist, dass Sie zustandsbehaftete Klassen und Hooks nicht mischen. Unter der Haube könnte der Flatter-Renderer immer noch Hooks und ihre Reihenfolge zählen, wenn sie innerhalb der build -Methode aufgerufen werden, und sie richtig verwalten.

Wenn es in Zukunft möglich wäre, funktionale Widgets zu erstellen, ist das keine bahnbrechende Veränderung. Außerdem wäre es abwärtskompatibel, da es vorhandene Apps nicht beschädigt.

Ich sehe kein offensichtliches Problem bei der Verwendung von Hooks innerhalb StatelessWidget , das die Vorteile der Verwendung von Hooks wie Komposition zunichte machen würde.

Ich bin mir jedoch nicht sicher, wie es im Vergleich zu Fällen wie useCallback usw. reagieren würde, verglichen mit der Möglichkeit, Instanzmethoden trotzdem zu verwenden

Das Argument „Wir müssen das hinzufügen, weil React-Entwickler wütend sein werden“ ist ungültig. (siehe JSX-Diskussion mit über 500 Kommentaren).

Flutter ist Flutter, und es hat seine eigene Sprache und Designmuster.
Ich denke, wir sollten dem Framework nichts hinzufügen, nur um es React-Entwicklern vertrauter zu machen, sie können das Paket verwenden, wenn sie möchten.

Ich habe die Diskussion gelesen und ich denke, @Hixie als Flutter-Framework-Entwickler hat nur seine Seite des Problems gesehen (Implementierung und ... Zeug) und hatte weniger Perspektive darauf, wie Flutter-App-Entwickler (die seine Zielgruppe sind) denken und verwenden ihre Entwicklung.

Ich als Android-Entwickler hatte ein solches Problem, versuche, eine großartige Back-End-Struktur für meine Anwendungen zu entwickeln, ohne zu wissen, wie meine App-Benutzer erleben werden, wenn sie meine hässliche Benutzeroberfläche und schwer verständliche UX sehen.

Wie andere schon sagten, Haken sind großartig. egal wer es einführt, entweder böse FB oder Apple.
es funktioniert einfach. es trennt die Zustandslogik und ihre Lebenszyklen. Wir können einige nützliche andere Hooks übereinander bauen, unabhängige Widgets, APIs, Tools, ... aus App-Zuständen veröffentlichen, unsere vorproduzierten in anderen Projekten wiederverwenden, ....

Und ich denke, wenn das Vorab-Hinzufügen einer Zeile in pubspec.yaml zum Importieren von Material oder Cupertino schwierig ist, um eine einfache Hallo-Wort-App zu erstellen !!!, gibt es hier nichts zu diskutieren.
Aber da StatefullWidget für das Flutter-Ökosystem sehr wichtig ist, haben Hooks und seine Relevanz in der Zukunft von Flutter und seinem Ökosystem und der Flutter-Entwicklergemeinschaft eine größere Bedeutung.

Stellen Sie sich vor, wie die Entwicklung von Flatter-Apps einfacher, fehlersicher, leicht verständlich, erweiterbar, lesbar, debug-fähig, portabel, ... (jede gute Thin-Plus-Fähigkeit hier pls 😁) mit Hooks sein wird, die direkt vom Core (oder so etwas) unterstützt werden in der Mitte zwischen Kern und einigen komplexen Widgets wie Material, ...) besonders offiziell.

Um meinen Punkt besser zu verstehen, schauen Sie sich an, wie schrecklich die Android-Entwicklung mit Java und Support-Bibliotheken war und wie schick und süß Kotlin ist.
Es öffnet auch die Tür für andere gute Dinge wie Coroutines, Flow, AndroidX + Kotlin-Unterstützung, neues UI-System (Compose)
Sogar es hat die Java-Community dazu gedrängt, Kotlin-Futures in ihrem Eco zu starten und zu implementieren.

Also lassen Sie bitte jeden Puffer in Hooks fallen und reagieren Sie und tun Sie es einfach

Der Mangel an offizieller Hooks-Unterstützung ist der einzige Grund, warum ich nicht von React Native gewechselt bin.

Hooks machen das Leben so viel einfacher, dass ich es nie wieder auf die alte Art schreiben möchte

Ein erstaunlicher Teil von "native Hooks" ist, dass wir viele interne StatefulWidgets oder ... in diese einfach verständliche Form portieren können.
Auch als Flutter-Team erklären Flutter und Dart für einfach zu bedienende, leicht verständliche und schnelle Lernkurve. All dies kann mit Native Hooks wahr und besser werden.
Und (initState/dispose/setState/build) Weg ist nicht in diesem Pfad. (Wir brauchen sie möglicherweise im Backend der Plattform, aber nicht für neue Entwickler oder sogar Designer, die Code verwenden möchten, um nur ihre Ideen zu beschreiben (keine komplexe Logik))

Ich habe in diesem Thread gelesen, dass viele Leute begeistert davon sind, Hooks in Flutter zu verwenden, und einige offene Fragen zu Hooks:

  • Auswirkungen auf die Leistung/Messung – insbesondere die Effizienz des ständigen Aufrufs von Funktionen im Vergleich zu der Tatsache, dass dieser Zustand wiederverwendet werden kann, ohne eine neue Funktion aufzurufen.
  • Fähigkeit (Unfähigkeit?), gut mit globalen Tasten zu spielen und/oder sich effizient im Baum zu bewegen.
  • Hook-spezifische Unterstützung/Lints des Analysers.
  • Fähigkeit, sowohl mit heißem Neuladen als auch mit einfachen alten zustandsbehafteten/zustandslosen Widgets zu arbeiten.
  • Möglicher Bedarf für zusätzliche Framework-API.

Ich bin sicher, dass alle diese Fragen beantwortet werden können, aber sie zu beantworten ist nicht trivial. Das Problem ist nicht so sehr "sollten Hooks im Framework sein oder sollten Hooks in einem separaten Paket leben". Bis zu einem gewissen Grad ist diese Entscheidung bereits getroffen - flutter_hooks ist jetzt seit über einem Jahr auf pub.dev verfügbar und scheint ein beliebtes Paket zu sein. Um flatter_hooks zu einem wirklich ausgefeilten Erlebnis zu machen, bedarf es erheblicher Arbeit und Investitionen, die über das hinausgehen, was bereits getan wurde.

Ein Großteil dieser Arbeit _wurde_ bereits für Kern-Framework-Klassen geleistet, und es hat mehrere Ingenieurteams sowie mehrere Open-Source-Mitwirkende Jahre gekostet, um es an den Punkt zu bringen, an dem es ist. Manchmal scheint es eine Illusion zu geben: "Wenn wir es einfach mit Repo X zusammenführen, werden alle nicht behobenen Dinge behoben!" Aber die Art und Weise, wie diese Dinge passieren, ist, dass Menschen, die davon begeistert sind, die Arbeit erledigen, sie umzusetzen. @rrousselGit hat bereits viel Arbeit daran geleistet, und es sieht so aus, als ob mehrere andere Mitwirkende im Hooks-Repository dies auch getan haben.

Was ich versuche, auf den Punkt zu bringen, ist - Hooks können großartig funktionieren, ohne im Flutter-Repository zu sein, im Flutter-Repository zu sein, wird die Lösung seiner ausstehenden Probleme nicht beschleunigen, und dass jeder und jeder, der Hooks in Flutter arbeiten sehen möchte ist völlig befugt, dies zu verwirklichen.

Nun, meiner Meinung nach sollten Hooks stattdessen ein Sprachfeature sein, das Sync /Async -Generatoren ähnelt.
Es muss überhaupt nichts mit Flattern zu tun haben.

Die Probleme, die Hooks lösen, sind:

  • deklarative und reaktive Zustandsverwaltung.
    State ist zwingend erforderlich
  • Zustandszusammensetzung, um DRY zu beheben.
    Alle diese XXController müssen erstellt, aktualisiert und entsorgt werden, und es gibt keine Möglichkeit, diese Logik zu faktorisieren.
  • Lesbarkeit, da keine endlose Verschachtelung von Funktionen/Widgets erforderlich ist, um dieses Ergebnis zu erzielen

Aber eine alternative Syntax könnte sein:

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;
}

Dies erzielt den gleichen Effekt wie Flutter_hook, ist jedoch unabhängig von Flutter und mit mehreren Optimierungsfaktoren, die Flutter_hook nicht leisten kann.

Und das erlaubt im Grunde _alles_, Hooks zu verwenden, nicht nur Widgets.

Das ist eine interessante Idee. Es hört sich so an, als ob dort mehrere Sprachfunktionsanforderungen enthalten sind (so etwas wie defer von Go, so etwas wie ein deterministischer Destruktor von C++, eine gewisse Fähigkeit, Funktionen implizit in Objekte zu komponieren) - aber das ist nicht wirklich der richtige Ort um das zu verfolgen.

Ich denke, es wäre wertvoll, die Schmerzpunkte zu identifizieren, die Menschen haben, wenn sie keine Hooks in Flutter haben und Probleme speziell zu diesem Schmerz einreichen, ohne zunächst eine Lösung auszuwählen. Es ist jedoch durchaus möglich, dass einige dieser Schmerzpunkte nur Dinge sind, die das Framework erzwingt, um Ziele in Bezug auf Leistung, Qualität oder Kompromisse bei der Benutzerfreundlichkeit zu erreichen (wie in, wir könnten Schmerzpunkt X an der Stelle verbessern Kosten, um den Schmerzpunkt Y viel schlimmer zu machen).

So wie es jetzt aussieht, werde ich dieses Thema schließen. Es gibt ein gutes Paket, das sich mit dieser speziellen Lösung befasst, und die Lösung selbst ist nicht bereit, in ihrem aktuellen Zustand (aus den oben genannten Gründen) in das Framework integriert zu werden, und es ist nicht klar, ob die Lösung dies jemals wirklich tun würde profitieren von der Einbindung in das Framework.

@dnfield Hooks funktionieren „als Familie“ nur dann gut, wenn Sie alle Hauptanforderungen abgedeckt haben.

Es wäre sinnlos, Status-Hooks zu verwenden, wenn Sie dann an die Wand stoßen würden, wenn Sie nach Statusänderungen irgendwelche Effekte benötigen.

Jeder Hook-by-Design erfordert erhebliche Änderungen im Kern des Renderers oder die Einführung einer neuen Art von Kernkomponente.

Ein solcher Aufwand lohnt sich nicht für nur eine Art Haken (Schmerzpunkt), daher würde ich sagen, dass es unmöglich ist, dieses Problem als eine Menge kleinerer Probleme zu lösen. Der einzelne Haken ist es nicht wert, von zustandsbehafteten Komponenten zu wechseln, und es lohnt sich sicherlich nicht, signifikante Änderungen in der Rendering-Engine vorzunehmen.

Wenn dieses Problem sagen soll "Ich möchte, dass Flutter mehr wie React ist, aber auch wie Flutter", bin ich mir nicht sicher, wie umsetzbar es ist - und ein GitHub-Problem ist wahrscheinlich sowieso nicht der richtige Weg, um so etwas zu verfolgen, auch wenn wir so etwas sinnvoll nachverfolgen lassen.

Anders ausgedrückt: Wenn dies eine Bitte ist, den Kern von Flutter neu zu schreiben, ist dies nicht der richtige Weg, es anzugehen. Ich bin mir nicht sicher, was der richtige Weg wäre, es anzugehen, aber es würde wahrscheinlich damit beginnen, das Repository einfach zu forken und einen massiven Aufwand zu unternehmen.

Ich habe ein komisches Gefühl, wenn Hooks Leuten vorgestellt werden, die sie nicht kennen und andere Technologien pflegen.

Es scheint, dass die Antwort oft so etwas wie "Wenn Sie möchten, dass X wie React ist, verwenden Sie React" ist.

Meiner Meinung nach sind Hooks eine generische Lösung für viele Frontend-Probleme, bei denen Sie komplexe Datenlogik wiederverwenden müssen. Es ist eher eine Idee, die in jeder Technologie verwendet werden könnte.

Hooks erfordern jedoch eine Art Umdenken in Bezug auf den Datenfluss, bevor ihr Wert vollständig sichtbar wird. Ich denke, es könnte ein großes Problem sein, wenn Hooks in anderen Frameworks "angefordert" werden.

Ich denke, das React-Team hat großartige Arbeit geleistet, als es versucht hat, Hooks zu erklären, aber vielleicht erzeugt es Widerstand, weil Hooks stark mit React verwandt zu sein scheinen.

Ich denke, React wird so oft neben Hooks erwähnt, einfach weil sie hier erfunden wurden. React ist auch (bisher) die beste Informationsquelle über Hooks.

Im Allgemeinen würde ich den "Schmerzpunkt" als nicht in der Lage sein, ein Kompositionsmuster für die Datenlogik direkt in Flutter zu verwenden. Hooks sind nur ein Beispiel dafür.

Ich verstehe auch, dass die Einführung von Hooks eine riesige Aufgabe ist und ich muss sagen, dass ich nicht bereit bin, mich darauf einzulassen.

Ich persönlich verstehe das Argument "Die Community hat versucht, dieses Problem zu beheben, also müssen wir nichts tun" nicht.

Ein Community-Fix ​​bedeutet nicht, dass es von Google nicht besser gemacht werden könnte.
Nehmen Sie als Beispiel Ausdrücke innerhalb von Sammlungen.
Die Community könnte es "reparieren", indem sie Row/Column/ListView/... verzweigt, um null zu unterstützen.
Aber Google hat es behoben, indem es die Sprache geändert hat.

Auch Flutter sagt es selbst: Flutter ist von React inspiriert.
Dies ist daran zu erkennen, dass ein großer Teil der Verwendung eines Widgets im Wesentlichen darin besteht, wie eine React-Klasse verwendet wird.

Dies bedeutet zwar nicht, dass Flutter mit React übereinstimmen sollte, aber ich würde erwarten, dass das Flutter-Team zumindest einen genauen Blick auf React-Updates und sein Ökosystem wirft.
Dies sollte zumindest eine bessere Antwort darauf geben, warum „wir keine Hooks im Framework wollen“ als das Community-Argument.

@rrousselGit @pie6k

Ich persönlich finde die Hooks-API, so wie sie in React ist, ziemlich schwierig zu verstehen. Ich bevorzuge die Lebenszyklusmethoden und ihre beschreibende Benennung.

Ich weiß, dass dies ein "Ich-Problem" ist, aber ich unterstütze den Kommentar von @dnfield , der besagt, dass wir die Probleme vielleicht annehmen und Lösungen anders implementieren sollten.

Außerdem bin ich selten in eine Situation geraten, in der zwei separate Widgets dieselbe Logik teilen müssen (das habe ich als Hauptvorteil von Hooks verstanden?)

Und dass Flutter von React inspiriert ist, das ist in Ordnung, aber das bedeutet nicht, dass es für immer allen React-Mustern und -Architekturen folgen wird.
Eines der Hauptprobleme, die ich mit React hatte, ist, dass es so viele verschiedene Möglichkeiten gibt, etwas zu tun, und „empfohlene Praktiken“ ändern sich täglich. Ich verstehe, dass dies in der Natur des Software-Engineerings liegt, aber ich denke immer noch, dass, wenn es etwas Schlechtes an bestehenden Methoden gibt, versucht werden sollte, sie zu verbessern … anstatt verschiedene Methoden anzuhäufen, um dasselbe zu erreichen.

Ich hoffe, das bietet Ihnen eine etwas andere Perspektive und beleidigt niemanden.

Großen Respekt für deine Beiträge zur Flutter-Community.

Schade, dass dieses Thema geschlossen wurde. Es sieht so aus, als hätte das Flutter-Team keine Ahnung von Hooks oder kümmert sich nicht um den aktuellen Stand der Designmuster (ich hoffe, das ist nicht der Fall). Das ist für keine Technologie gut, Leute, die Hunderte von Stunden investieren, wollen wissen, dass das, was sie verwenden, erstklassig ist oder mit ihr mithalten kann, und im Moment sind Haken das produktivste Muster, und Flutter hinkt hinterher, aber Es wurde von den Betreuern nicht einmal in Betracht gezogen oder zugunsten einer überzeugend besseren Alternative außer Acht gelassen.

@cgarciae niemand ist ignorant, @dnfield hat es klar gesagt - anstatt zu versuchen, bestehende Lösungen einzupressen, öffnen Sie die Probleme für entsprechende Probleme, die Sie haben, das Flutter-Team wird sie bewerten und möglicherweise eine Lösung finden, die noch besser zu Flutter passt.

Dies ist eine Funktion, nach der die Community stark gefragt hat und fragen wird. Wenn das Problem nicht der richtige Ort ist, haben Sie eine Feature-Anfrage zur Registrierungsanforderung von der Community?

@SpajicM Ich bin mit "Nein" als Antwort völlig einverstanden.
Was ich nicht teile, ist die aktuelle Begründung.

Einige Notizen:

  • Haken sind ein wesentliches Merkmal von React, dem Vater von Flutter
  • Diese Ausgabe ist eine der am meisten positiv bewerteten auf Flutter
  • flutter_hooks ist ziemlich beliebt
  • Dan Abramov vom React-Team schlug vor, mit dem Team https://github.com/flutter/flutter/issues/25280#issuecomment -456404333 zu diskutieren

Diese sollten einige intensive Diskussionen über Hooks ermöglichen. Nicht unbedingt umsetzen, aber zumindest erforschen.

Am Ende läuft es auf ein Kommunikationsproblem hinaus.

  • Hat das Flutter-Team das React-Team kontaktiert, wie von Dan Abramov angeboten?
  • Hat das Team mit Hook in React experimentiert?
  • Wurde eine Alternative zu den Problemen in Betracht gezogen, die Hooks lösen?

Davon wissen wir als Gemeinde nichts.

Um einen Schritt weiter zu gehen, finde ich es ironisch, dass der Community vorgeschlagen wurde, dieses Problem in „Was sind die Probleme, die Hooks lösen“ aufzuteilen, als das React-Team selbst anbot, dem Flutter-Team zu erklären, was diese Probleme sind.

@rrousselGit Ich denke, die Idee dahinter ist, die Probleme von der Flutter-spezifischen Seite direkt von Benutzern zu hören und dies als Ausgangspunkt zu nehmen, anstatt die Argumentation von React zu übernehmen, das heißt nicht, dass ihr Beitrag nicht wertvoll wäre.

Meiner Meinung nach wäre es gut, eine Möglichkeit zu haben, zwischen der Logik und dem Design des Widgets klar zu trennen - also stimme ich zu, dass es ein zu lösendes Problem gibt , aber die Art und Weise, wie React es tut, ist für mich etwas verwirrend, und ich wünschte, Flutters zukünftige Lösung hätte eine weniger dramatischer Paradigmenwechsel/Lernkurve. Ich habe keine Idee im Kopf, aber ich bin sicher, dass sich die Community zusammen mit einem Team etwas einfallen lassen könnte, wenn sie aufgeschlossen und nicht auf die bestehende Hooks-Implementierung fixiert ist.

Ich denke, der nächste Schritt ist, ein Problem mit dem Namen zu öffnen:

_"Flutter braucht eine bessere Möglichkeit, Widget-Logik zu isolieren"_

Ich denke, https://svelte.dev/ hat einen anderen und besseren Ansatz zur Lösung dieser Probleme. Als ersten Schritt sollte das Flutter-Team erkennen, dass es ein Problem gibt und wir eine Lösung brauchen.

Ich bin neu in Flattern und ich habe das Gefühl, dass die API eine Menge Boilerplate hat. Obwohl Dart ein Generikum hat, fühlt es sich an, als würde ich in Go programmieren, wo es üblicher/einfacher ist, zu kopieren und einzufügen. Ich hoffe, dass es eine große Umgestaltung geben wird, wenn NNDB gelandet ist, insbesondere wenn die Erweiterungsmethode in vollem Umfang verwendet wird. Eine schrittweise API-Abstraktion über so etwas wie eine Erweiterungsmethode könnte es wert sein, untersucht zu werden.

IMHO ist das Flutter-Team zu sehr von der Idee „alles ist ein Widget“ begeistert. Widgets eignen sich hervorragend für visuelle Elemente und Layouts, jedoch nicht zum Abrufen/Verarbeiten von Daten. Statt umständlicher FutureBuilder , StreamBuilder , TweenAnimationBuilder etc. würde ich eine funktionierende API bevorzugen:

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
    );
}

Tatsächlich verwendet Flutter an einigen Stellen bereits Hooks. Also statt mehr "Flattern"

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

Sie können verwenden
final data = MediaQuery.of(context);

Leider funktioniert dieser Mechanismus (Abonnement beim Erhalten) nur in Verbindung mit InheritedWidget.

Ich bin mir nicht sicher, wie viel mehr Fortschritte wir hier machen können, aber ich wollte einige Punkte ansprechen, die ich hier sehe:

  1. Es ist viel schwieriger, eine _Lösung_ zu evaluieren, als ein _Problem_ in einem GitHub-Issue zu evaluieren. Wenn Sie eine Lösung präsentieren, müssen Sie eine viel höhere Messlatte erreichen, um Akzeptanz zu erlangen. Sie müssen zeigen, dass die Lösung gut gestaltet ist, den Aufwand wert ist und dass sie einige echte Probleme löst, die dem erforderlichen Aufwand entsprechen (einschließlich nicht nur anfänglicher Prototypenerstellung und Implementierung, sondern auch laufender Wartung und Qualität). . Mit anderen Worten, ein Problem, bei dem wir einen bestimmten Problempunkt bei der Verwaltung von Daten und Widget-Status diskutieren, wird wahrscheinlich zu einer Reihe von Lösungen führen, von denen einige in das Framework übernommen werden könnten, einige davon zu Paketen von Drittanbietern werden könnten und einige davon wäre schön, kostet aber einfach zu viel.

  2. Google-Ingenieure, die an Flutter und Dart arbeiten, sind immer bestrebt, es besser zu machen, und sind im Allgemeinen immer beschäftigt. Das Gleiche gilt für die vielen Nicht-Google-Ingenieure, die zu Flutter beitragen. Das Schließen dieses Fehlers bedeutet nicht, dass kein Google-Ingenieur jemals daran arbeiten wird, Hooks mit Flutter besser funktionieren zu lassen. Die Tatsache, dass das Hooks-Paket einem Community-Mitglied gehört, mindert in keiner Weise die Qualität des Pakets oder seinen Wert – noch mindert es die Fähigkeit, einige der in diesem Fehler identifizierten Mängel zu beheben, zum Beispiel eine bessere Unterstützung für Analyse/Linting

  3. Es gibt verschiedene Gründe, ein Feature zu akzeptieren oder abzulehnen. Manchmal ist es so, dass das Feature wirklich cool ist, aber nicht ganz zur Architektur passt. Manchmal sieht das Feature oberflächlich gut aus, hat aber einige große Mängel, die es nicht angesprochen hat. Manchmal ist das Feature großartig, es würde mit ausreichendem Aufwand passen, aber der Aufwand, den es kostet, überwiegt den Wert, den es den Benutzern bietet, oder würde die Zeit für andere, noch wertvollere Features verkürzen. Insbesondere bei Flutter ist es manchmal nur so, dass wir eine stark geschichtete Architektur haben, die eine Erweiterung durch Pakete von Drittanbietern ermöglicht, und oft ist es besser, die Verlegung beizubehalten und Drittanbietern zu ermöglichen, großartige Arbeit zu leisten, als etwas Neues in das Framework aufzunehmen. Wir tun dies selbst in Paketen wie dem neuen Animationspaket, das unter https://github.com/flutter/packages/tree/master/packages/animations lebt.

Schließlich war ich am anderen Ende davon. Ich bin selbst ein Paketbetreuer, und ich habe Feature-Vorschläge abgelehnt bekommen, die mein Paket einfacher zu warten oder zu entwickeln gemacht hätten. Mein einziger Rat ist, wenn Sie ein tolles Paket haben, das Ihnen gefällt, arbeiten Sie weiter daran. Andere Leute werden es erkennen und ebenfalls helfen, egal ob es in diesem Repo enthalten ist oder nicht.

Das neue Android ComposeUI hat Hook-ähnliche Zustände: (Vorschau 2)

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

Auch das neue iOS SwiftUI hat ähnliche Dinge (aber es ist intern):

// 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)

Stellen Sie sich vor, die swiftUI von iOS verwendet onCreate, onInit, onUpdate, onExit, ... 🤢

Aber das beste Framework (natürlich ist es Flutter) widersteht immer noch der Idee, Hooks zu verwenden, warum?
Weil es wie React/ReactNative aussieht !!! oder einige erstaunliche Zitate vom Betreuerteam:

Ich ziehe es vor, die Boilerplate zu sehen

offensichtlich gegen die Flatteridee, UI mit deklarativer Syntax zu schreiben

Ich denke, Hooks Mixin ist eine gute Lösung.
Haben Sie Hooks überall dort, wo wir möchten, und berühren Sie keine Entwicklercodes und -frameworks im alten Stil.
Aber diese Idee und alle anderen großartigen Ideen erfordern eine starke Integration mit Kernbibliotheken, und es ist gut zu sehen, dass Kernbetreuer diese Funktionen erstklassig unterstützen.
Ich kann mir auch eine Zukunft nach der Hook-Integration vorstellen, die viele Top-Level-Framework-Bibliotheken (wie Material) stark unterstützen und sogar in ihnen verwenden.

Flutter könnte schöner sein:

// 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 stimme voll und ganz zu. Der Mangel an erstklassiger Unterstützung für alles Hookartige (oder anders ausgedrückt – alles, was eine ordnungsgemäße Komposition wiederverwendbarer Geschäftslogik ermöglicht) ist eigentlich der einzige Grund, warum ich Flutter nicht für mein letztes Projekt ausgewählt habe.

2. Die Tatsache, dass das Hooks-Paket einem Community-Mitglied gehört, mindert in keiner Weise die Qualität des Pakets oder seinen Wert – noch mindert es die Fähigkeit, einige der in diesem Fehler identifizierten Mängel zu beheben, zum Beispiel eine bessere Unterstützung für die Analyse /fusseln

Machen Community-Mitglieder Ghost-Pakete? Ja. Wird Google den Kern von Flutter austricksen? Nun, basierend auf Ihrer Haltung hier scheint das eine Möglichkeit zu sein. Zu behaupten, dass Core Flutter genauso konsumierbar ist wie Community-Pakete, ist ... bestenfalls falsch und schlimmstenfalls eine Lüge.

Darüber hinaus hat sich immer wieder gezeigt, dass es keine Rolle spielt, was die Community will oder braucht, es sei denn, @Hixie , der eine Affinität dafür gezeigt hat, persönliche Vorlieben zu verwenden, um Community-Anfragen zu überschreiben, es sei denn, es gibt eine Zustimmung. Ohne Buy-In geht es nicht. Und wenn das nicht der Fall ist, dann ist der Entscheidungsprozess zu undurchsichtig, um etwas anderes zu sehen.

Was mich interessiert, ist, dass die Leute, die entscheiden, ob Features leben oder sterben, anscheinend sehr wenig Geschäftserfahrung in der Entwicklung mobiler Apps haben. Diese Sichtweise wird immer die besten Erkenntnisse darüber liefern, welcher Zucker in Flutter gemischt werden sollte.

Ich denke, wir brauchen einen formalisierten Prozess, um zu entscheiden, welche Funktionen es in Flutter schaffen, der der Community mehr Gewicht verleiht, um zum Entscheidungsprozess beizutragen. Offensichtlich nicht 100 %, aber im Moment fühlt es sich an, als wären es ungefähr 5 %, und super schuppige 5 % dazu. @timsneath

Es ist viel schwieriger, eine Lösung zu bewerten, als ein Problem in einem GitHub-Issue zu bewerten

Das React-Team hat gleich zu Beginn dieser Ausgabe angeboten, seine Gründe für Hooks zu erläutern.
Dies sollte die Notwendigkeit, zu erklären, warum Hooks benötigt werden, vollständig abdecken, da niemand besser in der Lage ist, Hooks zu erklären als das React-Team selbst.

Luke, ich respektiere und schätze deine Leidenschaft, aber bitte hör auf mit den Ad-hominem-Angriffen. Wir alle arbeiten daran, die bestmögliche Plattform aufzubauen, indem wir alle Arten von Kompromissen eingehen, die auf Ressourcenkapazität, Benutzerforschung, Stakeholder-Input, Kundenbedürfnissen und Community-Input basieren.

Seien Sie freundlich, bitte. https://github.com/flutter/flutter/blob/master/CODE_OF_CONDUCT.md

Keine Ad-hominem-Angriffe beabsichtigt, danke für das Feedback. Gemäß dem CoC sollten wir vielleicht zusammenkommen, um zu besprechen, was ich zu kommunizieren versuche.

Die Leute, die anderer Meinung sind, sollten sich zusammensetzen, versuchen, die Standpunkte des anderen zu verstehen, und daran arbeiten, ein Design zu finden, das die Bedenken aller anspricht.

Gibt es dazu ein Update oder wo können wir eine Lösung koordinieren? Ich stoße bei meinen Flutter-Projekten darauf, insbesondere bei Animationen und Übergängen. Hooks helfen dabei, unter anderem diesen initState - und dispose -Zustand in einer einzigen Funktion zu kapseln und diese Funktion einfach zu verwenden, anstatt alles einzurichten.

Zumindest für einen externen Beobachter/Benutzer von Flutter und nicht für einen Plugin-Betreuer hat es den Eindruck, dass es berechtigte Bedenken gegeben hat, die sich nicht angehört anfühlen, wie das andere Problem mit Flutter Overlays (#50961 ), und sie scheinen eher als keine echten Probleme für die Benutzer als für die Betreuer abgetan zu werden. Nochmals, keine Respektlosigkeit gegenüber den Betreuern, dies ist nur meine Meinung als jemand, der diesen Problem-Thread beiläufig liest, ich bin nicht allzu vertraut mit anderen Problemen, die anders sein könnten.

Wie können wir vor diesem Hintergrund allgemeiner vorgehen, wenn wir über Lösungen für Probleme nachdenken, die Benutzer scheinbar berechtigterweise haben? Ich weiß, dass Rust ein interessantes RFC-System hat, das gut für das Entwerfen neuer Lösungen zu funktionieren scheint.

@satvikpendem Der RFC-Prozess hier besteht darin, einen Fehler zu melden, der das Problem beschreibt, und dann, sobald das Problem klar beschrieben ist, mögliche Lösungen zu diskutieren.

Es scheint, dass die Probleme bisher erklärt wurden, also können jetzt Lösungen diskutiert werden, ausgehend von Ihrem Kommentar. Was können wir als nächstes tun, gibt es andere Lösungen, die besser funktionieren als Haken oder ähnliches?

Wenn Sie mir den Fehler # mitteilen, kann ich Sie wissen lassen, ob das Problem ein Problem so detailliert beschreibt, dass es sinnvoll ist, mit der Diskussion möglicher Lösungen zu beginnen.

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

Ich denke auch, dass wir Dans Kommentar weiterverfolgen sollten: https://github.com/flutter/flutter/issues/25280#issuecomment -456404333
Was war das Ergebnis dieser Diskussion?

Hallo Remi, vielen Dank für Fehler #51752. Ich weiß, dass Sie eine Menge Zeit in diesen Bereich investiert und hier sehr wertvolle Pakete beigesteuert haben. Danke x1000 dafür!

Um den Kommentar von @dnfield zu wiederholen, scheinen wir uns noch nicht auf den Problembereich und seine Bedeutung eingestellt zu haben. Der obige Fehler ist ein nützlicher Schritt in Richtung dieses Ziels und/oder bei der Diskussion möglicher Ansätze für das Problem. Ihre Folgefrage hier geht davon aus, dass ein Gespräch mit dem React-Team der erste Schritt von hier aus ist, aber wenn wir noch keine Ausrichtung auf den Problemraum haben, scheint das verfrüht.

Vielleicht können wir vollständige Beispiele von Apps zeigen, die solche Probleme haben, die mit Hooks behoben würden. Wir würden sie nicht unbedingt mit Haken umschreiben, sondern nur zeigen, wie viel Kopieren und Einfügen es gibt. Wäre das etwas, das der Diskussion zugänglich wäre, @timsneath? Oder würden Sie an etwas anderes denken? Ich versuche herauszufinden, wie ich den Problemraum so klar wie möglich zeigen kann.

:wave: @timsneath
Um ehrlich zu sein, verstehe ich nicht ganz, warum eine Diskussion mit dem React-Team verfrüht wäre.

Auch ohne die Nachfrage der Community nach Hooks wäre eine Diskussion mit dem React-Team immer noch sehr wertvoll.
React hat viele Ähnlichkeiten mit Flutter und sie haben ein paar zusätzliche Jahre Erfahrung im Umgang mit Widgets-ähnlichen Objekten.

Mit ihnen zu diskutieren kann nur Vorteile für beide Seiten bringen.

Als Beispiel:
Nachdem ich flatter_hooks erstellt hatte, wurde ich von Dan kontaktiert, um zu besprechen, wie ich mit Hot-Reload für Hooks umgegangen bin.
Meine Antwort war "Es gab fast nichts zu tun, weil Flutter eine getippte Sprache verwendet".
Ein paar Monate später verbesserten sie das Hot-Reload von React, indem sie etwas Ähnliches wie Typen mit Babel generierten

Ich bin mir sicher, dass viele solcher Interaktionen stattfinden könnten, wenn das Team von Flutter und React darüber diskutieren würde, und beide Techniker würden Fortschritte machen.

Einige offene Fragen, die ohne ein bestimmtes Problem gestellt werden könnten:

  • Warum Haken?
  • Warum Suspense/Concurrent-Modus?
  • Warum Portale?

@satvikpendem Der RFC-Prozess hier besteht darin, einen Fehler zu melden, der das Problem beschreibt, und dann, sobald das Problem klar beschrieben ist, mögliche Lösungen zu diskutieren.

Bedeutet das, dass alle Diskussionen, die kein Fehler sind, ignoriert werden? Ich dachte, der Zweck von RFC sei für Dinge, die keine Fehler sind, sondern normalerweise, um subjektivere Dinge wie Entwicklererfahrung oder Tooling-Semantik zu erweitern.

Wenn jemand sagt: „Ich denke, wir sollten Hooks haben, weil sie über mehrere Frameworks hinweg idiomatisch werden und die Leute von verbesserter Erfahrung und Produktivität berichten“, ist das eine berechtigte Diskussion, aber es ist kein reproduzierbarer Fehler.

Ich bin mir absolut sicher, dass niemand gesagt hat: "Diskussionen, die kein Fehler sind, werden ignoriert". Kommen Sie, lassen Sie uns in gutem Glauben zusammenarbeiten und einander mit Respekt und Höflichkeit behandeln. Wir alle geben hier unser Bestes, aber mit vielen anderen konkurrierenden Fehlern, Designs und Ideen, die um unsere Aufmerksamkeit konkurrieren :)

@lukepighetti , ironischerweise ist "wir sollten Hooks haben, weil andere Frameworks sie haben" genau die Art von Konversation, die wir eigentlich zu vermeiden versuchen - weil es zu einem Design führt, das per Definition für die Bedürfnisse anderer Frameworks optimiert ist. Dabei ist es sehr hilfreich, das Problem zu beschreiben, das wir im Zusammenhang mit Flutter zu lösen versuchen, da uns das hilft, uns alle darauf zu einigen, ob das Problem dasselbe ist oder nicht, ob die Lösung dieselbe sein sollte usw.

@rrousselGit – sicher, es gibt einige nützliche allgemeine Gespräche, die wir mit dem React-Team führen könnten. Ich begrüße das Angebot, und vielleicht sollten wir das irgendwann tun. Sie haben mit Sicherheit eine Menge Klugheit in diesem Team, und ihr Angebot ist sehr liebenswürdig und freundlich. Im Moment würden wir hauptsächlich mit ihnen sprechen, weil Sie es uns gesagt haben, und nicht, weil wir spezifische Fragen haben, über die wir informiert genug sind :)

Und auch nur zur Erinnerung: "Das Flutter-Team" sind nur die Leute, die zu Flutter beitragen. Einige Mitwirkende arbeiten für Google, und einige Mitwirkende spielen eine stärkere Rolle bei der Steuerung der Architektur des Projekts, aber Sie gehören ebenso zum Flutter-Team wie alle anderen, die zum Projekt beitragen :)

Wie immer – vielen Dank – für Ihre Geduld bei der Diskussion, für Ihre Beiträge zur Community, dafür, dass Sie das Projekt mit kreativen Ideen in diesem Bereich weiter vorantreiben!

Zur Verdeutlichung: „Fehler“, wie wir ihn verwenden, ist ein allgemeiner Begriff, der sich auf alles bezieht, was zu einer Änderung führen könnte. Könnte ein Anwendungsfall sein, könnte eine Idee sein, könnte ein Logikfehler sein, könnte ein Tippfehler in der Dokumentation sein, etwas Verwirrendes auf der Website, was auch immer.

Vielleicht können wir vollständige Beispiele von Apps zeigen, die solche Probleme haben, die mit Hooks behoben würden. Wir würden sie nicht unbedingt mit Haken umschreiben, sondern nur zeigen, wie viel Kopieren und Einfügen es gibt.

@satvikpendem Wenn das Problem "Meine Anwendung hat zu viele Textbausteine" lautet, dann ist dies sicherlich ein Fehler, den Sie einreichen sollten, und wir können besprechen, wie die Angelegenheit verbessert werden kann. Erwähnen Sie hier die Fehlernummer, damit wir wissen, dass wir das Gespräch in Ihrem Fehler fortsetzen können.

Danke für den Kommentar @Hixie. Mein Problem wird weitgehend von demselben Fehler abgedeckt, den @rrousselGit erwähnt hat (#51752), also glaube ich nicht, dass ich mehr hinzuzufügen habe, basierend auf dem, was ich in dieser Ausgabe gelesen habe.

@timsneath Ich bin mir nicht sicher, ob ich deinen Kommentar zu @lukepighetti verstehe , da es sich so anfühlt, als hätten wir das Problem ein paar Mal im Zusammenhang mit Flutter beschrieben, wie in dieser Ausgabe, Nr. 51752, und anderen. Was müssten wir noch einbeziehen? Wie können wir Ihnen helfen, besser über diesen Problembereich informiert zu sein, sodass Sie, wenn wir mit dem React-Team oder anderen sprechen, über genügend Wissen verfügen, um fundierte Fragen zu stellen, wie Sie sagen?

Ich stimme zu, dass wir Dinge nicht von anderen Frameworks kopieren sollten, nur weil React sie zum Beispiel hat, also könnte es hilfreich sein, andere Lösungen für dieses Problem der Code-Duplizierung zu sehen. Der Gründer von Vue @yyx990803 hat einige seiner Gedanken in Vues RFC (https://www.github.com/vuejs/rfcs/tree/function-apis/active-rfcs%2F0000-function-api.md) gepostet, was hilfreich wäre durchgehen. Ein besonderer Blick auf die Abschnitte darüber, welche Probleme gelöst werden und warum sie bezüglich der klassenbasierten API respektvoll anderer Meinung sind, ist nützlich, um sie durchzulesen.

Danke für die Klarstellung @Hixie , ich habe diese breitere (möglicherweise interne?) Definition von "Bug" falsch verstanden.

@timsneath Ich bin mir nicht sicher, ob ich dir folge. Eine andere Gruppe von Menschen, Core React-Entwickler, hat bereits eine Reihe von Problemen identifiziert und kommuniziert, eine Lösung in einem architektonisch ähnlichen Framework erstellt, und viele Front-End-Teams über mehrere Frameworks hinweg berichten von Erfolgen. Ich sehe keinen Hinweis darauf, dass dies ein GitHub-Problem "Lösung vor Problem" ist. Es scheint, dass @Hixie nicht zustimmt, dass es ein zu lösendes Problem gibt, und es scheint, dass dies auf Stil- oder Wartungsentscheidungen basiert, die nicht die Vorteile der Entwicklererfahrung widerspiegeln. Ich sage das mit größtem Respekt, während ich versuche zu verstehen, woher die Zurückhaltung gegenüber diesem RFC kommt.

Normalerweise empfehle ich keine Parroting-Features, aber der RFC für Hooks ist nicht ohne Stand der Technik mit guter Begründung. Der Stand der Technik ist beim Kernreaktionsteam erhältlich, und jede Begründung, die wir finden, wird wiederholen, was sie können und kommuniziert haben. @rrousselGit scheint sich dafür einzusetzen, dass Sie ein Treffen mit ihnen vereinbaren, um dieses Thema zu besprechen, da sie weitaus mehr Einblicke bieten können als wir in einem GitHub-Problem.

Als Meta-Problem wäre es für mich persönlich hilfreich, wenn es einen konkreten Prozess gäbe, um breite RFCs in die flutter/flutter -Roadmap aufzunehmen, die von der Community hervorgebracht werden. Wir haben ein Sprichwort, dass externe Stakeholder diejenigen sind, die die schwierige und notwendige Arbeit wollen, deshalb müssen sie einbezogen und ernst genommen werden. Extern im Kontext von flutter/flutter wäre non-team, non-google, non-GDE.

Ich habe unseren RFC-Prozess in unserem Wiki dokumentiert.

Extern im Zusammenhang mit Flattern/Flattern wäre non-team, non-google, non-GDE.

Wenn Sie einen RFC einreichen, sind Sie per Definition ein Mitglied des Teams.

Mein Problem wird weitgehend von demselben Fehler abgedeckt, den @rrousselGit erwähnt hat (#51752).

In diesem Fall empfehle ich, an dieser Diskussion teilzunehmen; Dieses spezielle Thema ist geschlossen, aber dieses ist offen. Es gab ein paar Beschreibungen von Vorschlägen in dieser Ausgabe, aber keiner schien gute Arbeit zu leisten. Eine besonders klare Beschreibung von "Hooks" gab es dort noch nicht, es wurde nur am Rande erwähnt.

Ich verstehe immer noch nicht, warum wir das Problem erklären sollen, wenn sowohl die Probleme als auch die vorgeschlagenen Lösungen von React und Vue sehr klar dokumentiert sind.

Der RFC von Hooks enthält etwa 1400 Kommentare, Einführungsvideos, Dokumentationen und Artikel von vielen klugen Köpfen.

Über die Lösung dieser Probleme können wir uns nicht einig sein. Aber es sollte nicht nötig sein, die Probleme zu erklären

Das Problem wurde in #51752 erklärt, oder nicht? Ist das nicht das Problem?

(Zur Begründung: Weil es keine effektive Möglichkeit ist, mit diesem Entwicklungsteam zu kommunizieren, ein Entwicklungsteam auf einen RFC mit 1400 Kommentaren für ein anderes Produkt zu verweisen. Es tut mir leid, wenn ich das Gefühl habe, begriffsstutzig zu sein.)

Tut mir leid, den Megathread zu pingen. Ich wollte nur allen, die diesem Beitrag folgen, sagen, dass ich ein paar weitere Gedanken aus der React-Perspektive in https://github.com/flutter/flutter/issues/51752#issuecomment -665380355 hinterlassen habe und gerne antworten würde Weitere Fragen, ob das nützlich wäre.

Ich wollte auch die Hoffnung zum Ausdruck bringen, dass dieser (und verwandte Threads) zivil bleiben und die Betreuer nicht mit Argumenten wie "es funktioniert für React" unter Druck setzen. React und Flutter haben signifikante Unterschiede im Programmiermodell, und React Hooks verlassen sich besonders stark auf einige Nuancen von uns. Sie haben dadurch auch einige Macken, die viele vielleicht nicht akzeptieren.

Ich habe meine Meinung zu Haken geändert. Ich denke, sie sind ein fantastisches Muster, aber ich habe gerade einen React Native-Vertrag abgeschlossen, und Hooks haben (meiner Meinung nach) das Entwicklungssystem für sehr wenig Gewinn fürchterlich fragmentiert. Flutter verwendet derzeit ein Muster, das den Komponenten der React-Klasse sehr ähnlich ist, und es gibt eine Menge Werkzeuge, die darum herum gebaut wurden. Wenn das Framework auf Hooks als primäre Zustandsverwaltungslösung umsteigen würde, würde es alle bestehenden Arbeits- und Denkmuster aufbrechen, die Flutter-Entwickler für sehr geringen Gewinn verwenden.

Ich denke, es gibt ein Argument dafür, dass Hooks ein überlegenes Muster für die produktive Entwicklung sind, aber ich denke, es gibt ein überzeugenderes Argument (wie das Kernargument von dartfmt), dass Konsistenz im Laufe der Zeit besser als „besser“ ist.

Ich sollte auch beachten, dass wir im Umgang mit neuen React-Entwicklern oft auf Hindernisse mit Haken stoßen, die zu unerwarteten Ergebnissen führen, und ihnen erst beibringen müssen, Klassenkomponenten zu verwenden. (Ein guter Vergleich ist das Phänomen, dass es neuen Entwicklern leichter fällt, for-Schleifen im Vergleich zu Sammelmethoden wie map/reduce/filter/fold zu verwenden). Haken sind ein fortgeschrittenes Muster und wir nehmen das manchmal als selbstverständlich hin. Das Frustrierende hier ist, dass die React-Community die Dokumentation und Unterstützung für Klassenkomponentenmuster schnell auslaufen lässt, was es schwieriger macht, diese Ausbildung oder Option für neue Entwickler anzubieten.

Ich hatte in der anderen Ausgabe Nr. 51752 erwähnt, dass wir vielleicht daran arbeiten sollten, eine Flutter-spezifischere Version von Hooks zu erstellen, da Hooks selbst einige Nachteile zu haben scheinen, wie das useEffect(() => ..., [] ) -Muster für nur einmaliges Rendern. @Hixie hat eine interessante Version mit dem Property- und PropertyManager-Muster erstellt, das etwas Ähnliches wie Hooks zu tun scheint, aber diese Nachteile möglicherweise nicht hat. Wir sollten uns mehr mit Alternativen zu Hooks befassen, denn zumindest für Flutter scheint es etwas zu geben, das besser funktioniert als Hooks im React-Stil, aber dennoch die gleichen Probleme löst.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen