保持 Widget.build 内部的纯净

保持 Widget.build 内部的纯净

Provider 家族的隐式依赖

使用 Provider 时,开发者常在 build 方法中直接调用 Provider.of 或 watch :

dart 复制代码
  
Widget build(BuildContext context) {
  final user = Provider.of<User>(context); // 状态逻辑直接嵌入 UI
  final theme = context.watch<ThemeProvider>();
  return Text(user.name, style: TextStyle(color: theme.textColor));
}

这里的 build 方法不仅要描述 UI,还要处理状态订阅,一旦更换状态管理方式,所有 Provider.of 调用都需逐个修改,耦合度极高。

Bloc 的层级嵌套

Bloc 虽强调事件流分离,但在 UI 层仍需通过 BlocBuilder 嵌入状态逻辑:

dart 复制代码
  
Widget build(BuildContext context) {
  return BlocBuilder<CounterBloc, int>(
    builder: (context, state) { // 状态处理逻辑混杂在 UI 构建中
      return Text('$state');
    },
  );
}

BlocBuilder 作为 UI 组件的一部分,让状态管理的实现细节暴露在 build 方法里,组件无法脱离 Bloc 框架独立复用。

Riverpod 的即时订阅

Riverpod 的 ref.watch 虽简化了订阅,但仍需在 build 中显式声明依赖:

dart 复制代码
  
Widget build(BuildContext context, WidgetRef ref) {
  final counter = ref.watch(counterProvider); // 状态订阅与 UI 强绑定
  return Text('$counter');
}

build 方法被迫知晓 counterProvider 的存在,一旦 provider 定义变更,所有 build 的引用处都要调整,违背了"UI 只关心数据,不关心数据来源"的原则。

为什么不应该在 build 中耦合状态管理?

  • 破坏单一职责: build 方法的核心是描述 UI 结构,混入状态订阅后,既要处理渲染逻辑,又要管理状态依赖,导致代码混乱。

  • 阻碍组件复用:耦合了特定状态管理逻辑的 UI 组件,无法在其他框架或场景中直接复用,降低了代码的灵活性。

  • 增加维护成本:当状态管理方案更换时,所有 build 方法中的订阅代码都需重构,牵一发而动全身。

替代方案

我在使用上述流行库后,发现他们的设计弊端,于是自己重新编写了一个简洁版的状态管理,没错状态管理就是一个很简单的东西,就像 Android 的 ViewModel 一样。本质上就是一个跟随生命周期的 vm 实例管理。但是不理解 flutter 这边的开发整的如此花里胡哨。

一种推荐:用 pub.dev/packages/vi... 解耦状态与 UI。

build 方法仅通过简单属性获取数据,彻底剥离状态管理细节:

dart 复制代码
// ViewModel 层封装状态逻辑
class UserViewModel extends ViewModel{
  final User user = User(name: 'Alice');
  // 状态更新逻辑完全封装在此
}


class UserPageState extends State<UserPage> with ViewModelStateMixin{
  late final UserViewModel _viewModel;
  void initState(){
    _viewModel = watchViewModel<UserViewModel>(factory: DefaultViewModelFactory(build:UserViewModel.new));
  }


  /// UI 层仅关注展示. 只持有 _viewModel。后续如何想替换底层的状态管理,
  /// 修改 _viewModel 的实现即可。
  Widget build(BuildContext context) {
    return Text(_viewModel.user.name); // 无任何状态订阅代码
  }
}

总结

让 UI 组件回归纯粹的展示职责,状态管理逻辑集中在 ViewModel ,不仅提升了代码可读性,还让组件复用和框架迁移变得轻松。当需要更换状态管理方式时,只需修改 ViewModel 内部实现, build 方法无需变动------这才是状态与 UI 应有的清晰边界。

相关推荐
好的佩奇11 小时前
Dart 之增强枚举
android·flutter·dart
好的佩奇14 小时前
蓝牙之无线电与通信距离
android·flutter·蓝牙
程序员老刘·2 天前
从短剧App的bug看响应式编程在AI时代的优势
flutter·ai编程·跨平台开发
传奇开心果编程2 天前
【Flutter踩坑排雷】第7课:巨型 build 函数坑|全部 UI 写在同一个 build,维护难、隐性异常
android·flutter·ios·移动开发·跨平台·dart·声明式ui
程序员老刘2 天前
从短剧App的bug看响应式编程在AI时代的优势
flutter·ai编程·客户端
恋猫de小郭3 天前
最近 Android 有什么更新:Android Dev Summit 2026 技术解读
android·前端·flutter
好的佩奇3 天前
Dart 之类修饰符
android·flutter·dart
好的佩奇014 天前
Dart 之类修饰符
android·flutter·dart
Jewel1054 天前
文字为什么总是不居中!记录一个bug
android·flutter·ios
2601_949847755 天前
Form-data 跨端三方库仓颉适配全流程
前端·javascript·flutter