Ich habe versucht, meine Flutter-App für die Provider 4.0.1
heutige 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
, SingleChildStatelessWidget
welche 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.3
aber natürlich muss ich mehr tun.
Mein ursprünglicher Code stammt aus diesem Tutorial .
Bearbeiten: Ich habe dieses Problem behoben, indem ich lazy: false
die 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: false
habe 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: false
jetzt 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: false
zu jedem Anruf hinzufügen Provider.of
und 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.
Antworten:
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 ...?quelle
listen: false
ist nicht die Standardeinstellung fürSingleChildStatelessWidget
?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
quelle
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:
quelle