【发布时间】:2023-03-14 05:32:01
【问题描述】:
我今天尝试升级我的 Flutter 应用以使用 Provider 4.0.1,但以下代码在将值分配给 null 时崩溃。
这是我尝试转换的代码。我只将SingleChildCloneableWidget 更改为SingleChildStatelessWidget,编译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');
在 null 上调用了 getter 'language'。收件人:空
这在 Provider 3.0.3 上运行良好,但显然我需要做更多。
我的原始代码来自this tutorial。
编辑:我通过在流提供程序创建方法中添加lazy: false 解决了这个问题,但随后在此代码中出现了另一个错误。
Future<String> translate(BuildContext context, _term) async {
final String _languageCode = Provider.of<User>(context).language;
产生了这个错误:
发生了异常。 _AssertionError ('package:provider/src/provider.dart': 断言失败: line 213 pos 7: 'context.owner.debugBuilding || listen == 假 || _debugIsInInheritedProviderUpdate': 试图听一个 从小部件树外部与提供者公开的值。
这可能是由事件处理程序引起的(例如按钮的 onPressed) 调用 Provider.of 而不传递
listen: false。要修复,写:Provider.of(context, listen: false);
它不受支持,因为可能会毫无意义地重建小部件 关联到事件处理程序,当小部件树不关心时 关于价值。 )
我在上面的行中添加了listen: false,这似乎已经解决了这个问题,但是我尝试使用的下一个提供程序产生了这个错误:
试图从外部监听提供者公开的值 小部件树。
这可能是由事件处理程序引起的(例如按钮的 onPressed) 调用 Provider.of 而不传递
listen: false。要修复,写:Provider.of(context, listen: false);
它不受支持,因为可能会毫无意义地重建小部件 关联到事件处理程序,当小部件树不关心时 关于价值。 'package:provider/src/provider.dart': 失败 断言:第 213 行第 7 行:'context.owner.debugBuilding ||听== 假 || _debugIsInInheritedProviderUpdate'
我现在应该去每个我调用提供者的实例并添加listen: false吗?我需要有人来解释发生了什么变化以及为什么我在 Flutter 还很新,而且 Provider 的文档很少。有很多次我在代码中调用 Provider 并且最后一个错误没有返回代码位置。
现在是否总是需要 listen: false 而以前不需要它,或者我错过了其他东西?我开始在每次调用中添加 listen: false 以实例化 Provider 变量,它似乎正在工作,但这是正确的方法吗?我应该在每次调用Provider.of 时添加listen: false 并收工吗?
edit:每当从小部件树的可见部分之外调用提供程序时都会出现错误。这种区别很重要。
【问题讨论】:
-
更新时遇到同样的问题。问题是,如果我可能会或可能不会更改小部件树怎么办?我正在回滚。
标签: flutter