Absturz der Flatter-App nach der Konvertierung von Provider 3 in 4

8

Ich habe versucht, meine Flutter-App für die Provider 4.0.1heutige Verwendung zu aktualisieren, und der folgende Code ist beim Zuweisen eines Werts zu null abgestürzt.

Hier ist der Code, den ich konvertieren möchte. Ich habe nur geändert SingleChildCloneableWidget, SingleChildStatelessWidgetwelche OK kompiliert.

import 'package:provider/provider.dart';
import 'package:provider/single_child_widget.dart';

List<SingleChildStatelessWidget> providers = [
  ...independentServices,
  ...dependentServices,
  ...uiConsumableProviders
];

List<SingleChildStatelessWidget> independentServices = [
  Provider.value(value: Api()),
  Provider.value(value: Tbl()),
  Provider.value(value: Bill()),
  Provider.value(value: Sale()),
  Provider.value(value: Category()),
  Provider.value(value: Menu()),
];

List<SingleChildStatelessWidget> dependentServices = [
  ProxyProvider<Api, AuthenticationService>(
    update: (context, api, authenticationService) => AuthenticationService(api: api),
  ),
];

List<SingleChildStatelessWidget> uiConsumableProviders = [
  StreamProvider<User>(
    create: (context) => Provider.of<AuthenticationService>(context, listen: false).user,
  ),
    lazy: false
];

Ich habe es so implementiert:

StreamController<User> _userController = StreamController<User>();
Stream<User> get user => _userController.stream;

Der Absturz ereignete sich in dieser Zeile:

Future<void> _setFixedLanguageStrings(BuildContext context) async {

 User _user = Provider.of<User>(context);

 _user.homeString = await translate(context, 'Home');

Die Getter-Sprache wurde auf null aufgerufen. Empfänger: null

Das hat gut funktioniert, Provider 3.0.3aber natürlich muss ich mehr tun.

Mein ursprünglicher Code stammt aus diesem Tutorial .

Bearbeiten: Ich habe dieses Problem behoben, indem ich lazy: falsedie Erstellungsmethode des Stream-Providers hinzugefügt habe , aber später in diesem Code einen weiteren Fehler.

Future<String> translate(BuildContext context, _term) async {

  final String _languageCode = Provider.of<User>(context).language;

welches diesen Fehler erzeugt hat:

Ausnahme ist aufgetreten. _AssertionError ('package: provider / src / provider.dart': Assertion fehlgeschlagen: Zeile 213 Pos. 7: 'context.owner.debugBuilding || listen == false || _debugIsInInheritedProviderUpdate': Versucht, einen mit dem Anbieter offengelegten Wert von abzuhören außerhalb des Widget-Baums.

Dies wird wahrscheinlich durch einen Ereignishandler (wie onPressed einer Schaltfläche) verursacht, der Provider.of ohne Übergabe aufgerufen hat listen: false.

Um dies zu beheben, schreiben Sie: Provider.of (Kontext, hören: falsch);

Es wird nicht unterstützt, da das dem Ereignishandler zugeordnete Widget möglicherweise sinnlos neu erstellt wird, wenn sich der Widget-Baum nicht um den Wert kümmert. )

Ich listen: falsehabe der obigen Zeile hinzugefügt , die dieses Problem behoben zu haben scheint. Der nächste Anbieter, den ich verwenden wollte, hat jedoch diesen Fehler verursacht:

Es wurde versucht, einen Wert anzuhören, der mit dem Anbieter außerhalb des Widget-Baums verfügbar gemacht wurde.

Dies wird wahrscheinlich durch einen Ereignishandler (wie onPressed einer Schaltfläche) verursacht, der Provider.of ohne Übergabe aufgerufen hat listen: false.

Um dies zu beheben, schreiben Sie: Provider.of (Kontext, hören: falsch);

Es wird nicht unterstützt, da das dem Ereignishandler zugeordnete Widget möglicherweise sinnlos neu erstellt wird, wenn sich der Widget-Baum nicht um den Wert kümmert. 'package: provider / src / provider.dart': Fehlerhafte Zusicherung: Zeile 213 Pos. 7: 'context.owner.debugBuilding || listen == false || _debugIsInInheritedProviderUpdate '

Soll ich jetzt zu jeder Instanz gehen, in der ich einen Anbieter anrufe und hinzufüge listen: false? Ich brauche jemanden, der erklärt, was sich geändert hat und warum, da ich ziemlich neu bei Flutter bin und die Dokumente spärlich sind Provider. Es gibt viele Male, in denen ich Provider in meinem Code anrufe und dieser letzte Fehler keinen Code-Speicherort zurückgegeben hat.

Wird listen: falsejetzt immer benötigt, wenn es vorher nicht war oder habe ich etwas anderes verpasst? Ich fange an, listen: false für jeden Aufruf hinzuzufügen, um eine Provider-Variable zu instanziieren, und es scheint zu funktionieren, aber ist dies der richtige Ansatz? Sollte ich einfach listen: falsezu jedem Anruf hinzufügen Provider.ofund ihn einen Tag lang anrufen?

Der Fehler zeigt an, dass die App versucht hat, einen Wert außerhalb des Widget-Baums anzuhören, aber ich glaube nicht, dass dies der Fall ist, wie ich ihn innerhalb der Widget-Erstellungsmethode nenne. Wenn dieser Fehler korrekt ist, befinden sich alle meine Anbieter außerhalb des Widget-Baums. Der Code funktioniert seit einigen Monaten gut, die Abhörfehler sind nur bei diesem Update aufgetreten.

Markhorrocks
quelle
Habe das gleiche Problem beim Update. Was ist, wenn ich den Widget-Baum ändern darf oder nicht? Ich rolle zurück.
Dpedrinha

Antworten:

3

Ich habe das gleiche "Problem", wenn ich listen: falseüberall hinzufüge, wo ich Provider anrufe, ist das Problem weg, aber ich weiß nicht, ob das die richtige Lösung ist ...?

dukaric1991
quelle
Ich frage mich, warum listen: falseist nicht die Standardeinstellung für SingleChildStatelessWidget?
Markhorrocks
Es gibt keinen Fehler beim Hören: false, aber die Benutzeroberfläche wird nicht aktualisiert, sodass etwas anderes erforderlich ist, damit es funktioniert
Shakle
1

listen : false Wird aufgerufen, wenn die Daten nichts in der Benutzeroberfläche aktualisieren und verwendet werden sollten, z. B. wenn alle Karten in einem Widget entfernt werden, wenn auf die Schaltfläche geklickt wird.

Weitere Informationen finden Sie unter go_to_link

Khalil Khalil
quelle
0

listen:true Die Standardeinstellung ist logisch.

Es wird nicht in einem Ereignishandler angegeben, was nicht logisch ist.listen: false

Außerdem wird 4.1.0 irgendwie eine kürzere Alternative zu Provider.of haben:

context.read<T>() // Provider.of<T>(context, listen: false)
context.watch<T>() // Provider.of<T>(context)
Jaime
quelle