flutter - Flutter 在不使用 context.read() 的情况下调用 Riverpod 函数
问题描述
默认情况下,在定义Riverpod
提供者后,我们可以单击任何小部件来调用某些方法,例如从 Web 服务或其他东西获取数据。
例如:
context.read(washingServiceProvider.notifier).getService;
现在我的问题是如何getService
在不点击任何小部件的情况下调用它?当我尝试使用此代码时:
class GetServices extends HookWidget {
@override
Widget build(BuildContext context) {
final washing = useProvider(washingServiceProvider.notifier);
washing.getService();
return Scaffold();
...
}
我收到此错误:
E/flutter ( 3398): [ERROR:flutter/shell/common/shell.cc(103)] Dart Unhandled Exception: setState() or markNeedsBuild() called during build.
E/flutter ( 3398): This UncontrolledProviderScope widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
E/flutter ( 3398): The widget on which setState() or markNeedsBuild() was called was:
E/flutter ( 3398): UncontrolledProviderScope
E/flutter ( 3398): The widget which was currently being built when the offending call was made was:
E/flutter ( 3398): GetServices, stack trace: #0 Element.markNeedsBuild.<anonymous closure> (package:flutter/src/widgets/framework.dart:4217:11)
E/flutter ( 3398): #1 Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:4232:6)
E/flutter ( 3398): #2 ProviderElement._debugMarkWillChange.<anonymous closure> (package:riverpod/src/framework/base_provider.dart:660:16)
E/flutter ( 3398): #3 ProviderElement._debugMarkWillChange (package:riverpod/src/framework/base_provider.dart:664:6)
E/flutter ( 3398): #4 ProviderStateBase.exposedValue=.<anonymous closure> (package:riverpod/src/framework/base_provider.dart:900:16)
E/flutter ( 3398): #5 ProviderStateBase.exposedValue= (package:riverpod/src/framework/base_provider.dart:902:6)
E/flutter ( 3398): #6 _StateNotifierProviderState._listener (package:riverpod/src/state_notifier_provider.dart:92:5)
E/flutter ( 3398): #7 StateNotifier.state= (package:state_notifier/state_notifier.dart:162:31)
E/flutter ( 3398): #8 RequestStateNotifier.makeRequest (package:washing_app/core/service/network/request_state_notifier.dart:10:7)
E/flutter ( 3398): #9 WashingRequestNotifier.getService (package:washing_app/src/screens/dashboard/tabs/category_products/repository/washing_service_repository.dart:98:7)
E/flutter ( 3398): #10 GetServices.build (package:washing_app/src/screens/dashboard/get_services.dart:39:13)
E/flutter ( 3398): #11 StatelessElement.build (package:flutter/src/widgets/framework.dart:4648:28)
E/flutter ( 3398): #12 HookElement.build (package:flutter_hooks/src/framework.dart:417:27)
E/flutter ( 3398): #13 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4574:15)
E/flutter ( 3398): #14 Element.rebuild (package:flutter/src/widgets/framework.dart:4267:5)
E/flutter ( 3398): #15 StatelessElement.update (package:flutter/src/widgets/framework.dart:4655:5)
E/flutter ( 3398): #16 HookElement.update (package:flutter_hooks/src/framework.dart:379:11)
E/flutter ( 3398): #17 Element.updateChild (package:flutter/src/widgets/framework.dart:3350:15)
E/flutter ( 3398): #18 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4599:16)
E/flutter ( 3398): #19 Element.rebuild (package:flutter/src/widgets/framework.dart:4267:5)
E/flutter ( 3398): #20 StatelessElement.update (package:flutter/src/widgets/framework.dart:4655:5)
E/flutter ( 3398): #21 Element.updateChild (package:flutter/src/widgets/framework.dart:3350:15)
E/flutter ( 3398): #22 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6090:14)
E/flutter ( 3398): #23 Element.updateChild (package:flutter/src/widgets/framework.dart:3350:15)
E/flutter ( 3398): #24 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4599:16)
E/flutter ( 3398): #25 Element.rebuild (package:flutter/src/widgets/framework.dart:4267:5)
E/flutter ( 3398): #26 StatelessElement.update (package:flutter/src/widgets/framework.dart:4655:5)
E/flutter ( 3398): #27 Element.updateChild (package:flutter/src/widgets/framework.dart:3350:15)
E/flutter ( 3398): #28 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6090:14)
E/flutter ( 3398): #29 Element.updateChild (package:flutter/src/widgets/framework.dart:3350:15)
E/flutter ( 3398): #30 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6090:14)
E/flutter ( 3398): #31 Element.updateChild (package:flutter/src/widgets/framework.dart:3350:15)
E/flutter ( 3398): #32 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4599:16)
E/flutter ( 3398): #33 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4746:11)
E/flutter ( 3398): #34 Element.rebuild (package:flutter/src/widgets/framework.dart:4267:5)
E/flutter ( 3398): #35 StatefulElement.up
E/flutter ( 3398): [ERROR:flutter/shell/common/shell.cc(103)] Dart Unhandled Exception: setState() or markNeedsBuild() called during build.
E/flutter ( 3398): This UncontrolledProviderScope widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
我定义的提供者:
final washingServicesRepositoryProvider = Provider((ref) => WashingServiceRepository(ref.read));
final washingServiceProvider =
StateNotifierProvider<WashingRequestNotifier, NetworkRequestState<WashingServicesResponseStructure>>(
(ref) => WashingRequestNotifier(ref.watch(washingServicesRepositoryProvider)));
class WashingServiceRepository {
final Reader _reader;
WashingServiceRepository(this._reader);
Future<WashingServicesResponseStructure> getService() async {
try {
const _r = RetryOptions(maxAttempts: 3);
final _res = await _r.retry(() => _reader(dioProvider)
.post(
Server.$getData,
options: Options(
headers: {'Content-Type': 'application/json'},
),
)
..timeout(const Duration(seconds: 30)),
retryIf: (e) => e is SocketException || e is TimeoutException);
return WashingServicesResponseStructure.fromJson(_res.data as Map<String, dynamic>);
} on DioError catch (error) {
rethrow;
}
}
}
class WashingRequestNotifier extends RequestStateNotifier<WashingServicesResponseStructure> {
final WashingServiceRepository _washingServiceRepository;
WashingRequestNotifier(this._washingServiceRepository);
Future<NetworkRequestState<WashingServicesResponseStructure>> getService() =>
makeRequest(() => _washingServiceRepository.getService());
}
解决方案
推荐阅读
- python - 无法创建类,Python3(我是初学者)
- html - 如何计算特定访问的网址?
- react-native - React-Native 中的关闭重新加载页面
- python - re Python中捕获组的字符串操作
- arrays - 如何解析通过 Angular 5 中的查询参数传递的 JSON
- mysql - 如果不喜欢但不工作,我想隐藏 id SELECT * FROM character, character_actor WHERE character.id NOT LIKE character_actor.character_id;
- signalr-hub - 触发 SignalR Core 消息
- android - int android.support.v7.widget.GridLayoutManager.getItemCount()' 在空对象引用上
- regex - 如何大写和更改存储在变量中的字符串中的最后一个特殊字符?
- wordpress - 从跨域的 wp rest api 获取数据