保持 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 应有的清晰边界。

相关推荐
A懿轩A7 小时前
【2025版 OpenHarmony】GitCode 口袋工具 v1.0.1 更新发布:Flutter + HarmonyOS 封装导航栏进行跳转
flutter·harmonyos·openharmony·gitcode·开源鸿蒙
苦逼的搬砖工11 小时前
BLE 通信设计与架构落地
android·flutter
程序员老刘·11 小时前
跨平台开发地图:客户端技术选型指南 | 2025年11月 |(Valdi 加入战场)
flutter·跨平台开发·客户端开发
A懿轩A14 小时前
【2025最新】Flutter 编译开发 鸿蒙HarmonyOS 6 项目教程(Windows)
windows·flutter·华为·openharmony·开源鸿蒙
忆江南19 小时前
🔥 一句话解释 SNI
flutter
WaterFly19 小时前
Flutter入门概览4-UI入门篇
flutter
未来猫咪花19 小时前
告别卡顿和耗电!view_model 的 Pause 机制如何拯救你的 Flutter 应用
flutter
metaRTC21 小时前
webRTC IPC客户端Flutter版编程指南
flutter·webrtc·ipc
liuxf123421 小时前
鸿蒙Flutter,No Hmos SDK found.
flutter·华为·harmonyos
西西学代码1 天前
Flutter---Listview横向滚动列表(1)
flutter