flutter - 为什么 ChangeNotifierProvider 存在?
问题描述
根据此处的 Flutter 文档(https://flutter.dev/docs/development/data-and-backend/state-mgmt/simple),
控制状态管理的一种方法是在其后代之一是 Consumer 时使用 ChangeNotifierProvider(或 InheritedWidget),当底层 ChangeNotifier 更改时会重新构建该 Consumer。Flutter 的团队在官方 youtube Flutter 频道上重申了这种方法。
然而,这意味着一些业务逻辑元素(ChangeNotifier)现在是 Widget 树的一部分(否则就是关于 UI 的外观)。所以我不明白为什么这些类(ChangeNotifierProvider、InheritedWidget、Consumer)甚至存在。
特别是,为什么以下方法不是更好的:
- 业务逻辑是一个单例和一个 ChangeNotifier。
- 而不是 Provider(...),对于取决于业务逻辑的每个 Widget,只需执行以下操作:
BusinessLogicSingleton.instance.addListener(() {
setState(() {
});
在 initState(...)。
我在这里想念什么?
解决方案
跟进这个问题,下面的超简单类为我节省了很多样板代码和不合逻辑的代码(通过 Provider 等强制 ChangeNotifier 成为 Widget 树的一部分)
import 'package:flutter/material.dart';
//A class which makes it easier to worker with change notifier without provider/consumer which looks wrong since changenotifier shouldn't be forced into widgets tree for no reason
//eg widgets should represent UI and not business logic
class ListenerWidget extends StatefulWidget {
const ListenerWidget({Key? key,required ChangeNotifier notifier,required Widget Function(BuildContext) builder,void Function()? action}) : notifier=notifier,builder=builder,action=action,super(key: key);
final Widget Function(BuildContext) builder;
final ChangeNotifier notifier;
final void Function()? action;
@override
_ListenerWidgetState createState() => _ListenerWidgetState();
}
class _ListenerWidgetState extends State<ListenerWidget> {
void emptyListener(){
setState(() {
});
}
@override
void initState() {
widget.notifier.addListener(widget.action??emptyListener);
super.initState();
}
@override
void dispose() {
widget.notifier.removeListener(widget.action??emptyListener);
super.dispose();
}
@override
Widget build(BuildContext context) {
return widget.builder(context);
}
}
推荐阅读
- python - Python 3.3+,标准 venv 虚拟环境包有什么原因或问题吗?
- arrays - 在C中初始化后如何将列表分配给数组
- reactjs - 在 react 和 typescript 中解构 useState 中的状态
- angular - 如何在 Angular 中显示来自 JSON 对象的图像
- mysql - 无法创建 2 个外键
- flutter - 根据风味分离 pubspec.yaml 文件
- javascript - 使用 Fetch 方法发送请求
- sql - Postgres - Distinct + jsonb_object_keys 给出了在不能接受集合的上下文中调用的错误集合值函数
- html - 引导列类不遵循边距或容器流体类
- java - 控制器不使用 Feign 可分页排序