将提供程序3转换为4后Flutter应用程序崩溃 [英] Flutter app crash after converting Provider 3 to 4

查看:186
本文介绍了将提供程序3转换为4后Flutter应用程序崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我今天尝试将Flutter应用程序升级为使用Provider 4.0.1,并且以下代码在将值分配为null时崩溃.

I tried to upgrade my Flutter app to use Provider 4.0.1 today and the following code crashed on assigning a value to null.

这是我尝试转换的代码.我只将SingleChildCloneableWidget更改为SingleChildStatelessWidget即可编译.

Here is the code I am attempting to convert. I only changed SingleChildCloneableWidget to SingleChildStatelessWidget which compiled OK.

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

我是这样实现的:

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

崩溃发生在此行:

Future<void> _setFixedLanguageStrings(BuildContext context) async {

 User _user = Provider.of<User>(context);
 
 _user.homeString = await translate(context, 'Home');

getter'language'在null上被调用.接收者:null

The getter 'language' was called on null. Receiver: null

这与Provider 3.0.3正常工作,但显然我需要做更多.

This was working fine with Provider 3.0.3 but obviously I need to do more.

我的原始代码来自本教程.

我通过在流提供程序的create方法中添加lazy: false来解决该问题,但随后在此代码中又出现另一个错误.

edit: I fixed that problem by adding lazy: false in the stream provider create method but then another error later in this code.

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

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

产生此错误:

发生异常. _AssertionError('package:provider/src/provider.dart':断言失败:第213行pos 7:'context.owner.debugBuilding ||听== 假|| _debugIsInInheritedProviderUpdate':尝试收听 提供商从窗口小部件树外部暴露的价值.

Exception has occurred. _AssertionError ('package:provider/src/provider.dart': Failed assertion: line 213 pos 7: 'context.owner.debugBuilding || listen == false || _debugIsInInheritedProviderUpdate': Tried to listen to a value exposed with provider, from outside of the widget tree.

这很可能是由事件处理程序引起的(例如按钮的onPressed) 没有通过listen: false调用Provider.of的文件.

This is likely caused by an event handler (like a button's onPressed) that called Provider.of without passing listen: false.

要修复,请写:Provider.of(上下文,听:false);

To fix, write: Provider.of(context, listen: false);

它不受支持,因为可能无意义地重建窗口小部件 与窗口小部件树无关的事件处理程序相关联 关于价值. )

It is unsupported because may pointlessly rebuild the widget associated to the event handler, when the widget tree doesn't care about the value. )

我在上面的行中添加了listen: false,该行似乎已解决了该问题,但是我尝试使用的下一个提供程序产生了此错误:

I added listen: false to the line above which seems to have fixed that problem, however the next provider I attempted to use produced this error:

试图从提供商外部监听提供者公开的值 小部件树.

Tried to listen to a value exposed with provider, from outside of the widget tree.

这很可能是由事件处理程序引起的(例如按钮的onPressed) 没有通过listen: false调用Provider.of的文件.

This is likely caused by an event handler (like a button's onPressed) that called Provider.of without passing listen: false.

要修复,请写:Provider.of(上下文,听:false);

To fix, write: Provider.of(context, listen: false);

它不受支持,因为可能无意义地重建窗口小部件 与窗口小部件树无关的事件处理程序相关联 关于价值. 'package:provider/src/provider.dart':失败 断言:213行pos 7:'context.owner.debugBuilding ||听== 假|| _debugIsInInheritedProviderUpdate'

It is unsupported because may pointlessly rebuild the widget associated to the event handler, when the widget tree doesn't care about the value. 'package:provider/src/provider.dart': Failed assertion: line 213 pos 7: 'context.owner.debugBuilding || listen == false || _debugIsInInheritedProviderUpdate'

现在我应该去调用提供程序的每个实例并添加listen: false吗?我需要有人来解释发生了什么变化,以及为什么我在Flutter刚起步并且文档对于Provider稀疏.很多时候,我在代码中调用Provider,而最后一个错误没有返回代码位置.

Should I now go to every instance where I call a provider and add listen: false? I need somebody to explain what has changed and why as I am fairly new at Flutter and the docs are sparse for Provider. There are many times where I call Provider in my code and this last error did not return a code location.

listen: false现在不是以前总是需要的吗?还是我错过了其他事情?我开始在实例化Provider变量的每个调用中添加listen:false,它似乎正在工作,但这是正确的方法吗?我应该将listen: false添加到每个对Provider.of的呼叫中,然后每天打电话吗?

Is listen: false now always required when it wasn't before or have I missed something else? I am starting to add listen: false to every call to instantiate a Provider variable and it appears to be working but is this the correct approach? Should I just add listen: false to every call to Provider.of and call it a day?

edit:每当从窗口小部件树的可见部分之外调用提供程序时,都会发生错误.这种区别很重要.

edit: The error arises whenever the provider is called from outside the visible part of the widget tree. This distinction is important.

推荐答案

我有相同的问题",如果我在调用提供程序的任何地方都添加listen: false,问题就消失了,但是我不知道这是否是正确的解决方案. .?

I have the same "problem", if i add listen: false everywhere i call Provider the problem is gone but i dont know if thats the right solution...?

这篇关于将提供程序3转换为4后Flutter应用程序崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆