Flutter不使用context.read且无需点击调用Riverpod方法报错如何解决
错误原因
报错的核心是你在组件build方法的同步执行阶段直接调用了getService方法,该方法会触发StateNotifier更新状态,本质相当于在Flutter组件树构建流程中调用setState(),此时框架不允许标记新的组件需要重建,因此抛出异常。
解决方案
根据你的使用场景可选以下三种方案:
方案1:适配HookWidget的useEffect写法(最推荐当前场景使用)
将方法调用放在useEffect中,指定空依赖数组,会在组件首次挂载完成后异步执行,不会干扰当前构建流程:
class GetServices extends HookWidget { @override Widget build(BuildContext context) { final washing = useProvider(washingServiceProvider.notifier); useEffect(() { washing.getService(); return null; }, const []); return Scaffold( // 原有页面布局代码 ); } }
方案2:通用的帧回调写法
不依赖Hook语法的通用方案,在组件首帧渲染完成的回调中执行调用:
class GetServices extends HookWidget { @override Widget build(BuildContext context) { final washing = useProvider(washingServiceProvider.notifier); WidgetsBinding.instance.addPostFrameCallback((_) { washing.getService(); }); return Scaffold( // 原有页面布局代码 ); } }
方案3:Provider层自动初始化
如果这个Provider不管在哪被首次使用都需要拉取服务数据,直接在Notifier构造方法中触发请求即可,无需在组件层处理:
class WashingRequestNotifier extends RequestStateNotifier<WashingServicesResponseStructure> { final WashingServiceRepository _washingServiceRepository; // 构造方法中直接调用请求,Provider首次创建时自动触发 WashingRequestNotifier(this._washingServiceRepository) { getService(); } Future<NetworkRequestState<WashingServicesResponseStructure>> getService() => makeRequest(() => _washingServiceRepository.getService()); }
补充说明
如果你的getService需要根据变量变化触发重新请求,只需要在useEffect的依赖数组中加入对应的变量即可,核心原则是不要将会触发Provider状态更新的方法直接放在build方法的同步执行路径中。
内容的提问来源于stack exchange,提问作者DolDurma
相关产品推荐
相关产品推荐

