flutter 确实不需要 hooks

之前写过一篇文章:juejin.cn/post/756852...

最近有人在评论区指责我不懂 hooks、不懂 signals、不懂前端潮流。那篇文章中,我对 hooks 还保留了一些余地,认为某些场景下可能确实有其必要性。但直到我深入研究了 flutter_hooks 这个库的起源,我的想法发生了改变。

事情的起因是,该库作者在 github.com/flutter/flu... 中提出状态复用困难的问题,希望借鉴 React 的 hooks 模式来解决。但 Flutter 官方维护者并不认同 hooks 与状态复用之间存在必然联系,因此不打算提供官方支持。

尽管如此,作者在这几年里始终坚持自己的观点,创建了 flutter_hooks 库,将 React 的那套 API 完整地移植到了 Flutter 中。

我个人也反对将 hooks 引入 Flutter。如果问题是状态复用困难,难道 hooks 就是唯一的解决方案吗?显然不是。

我们完全可以借鉴 Android 的 LifecycleObserver 模式,将逻辑抽离出来实现最大化复用,达到与 hooks 相同甚至更好的效果。本质上,hooks 也是对生命周期的一种封装,只是它在封装生命周期之外还附加了许多额外功能。但这些额外功能与状态复用的核心问题关系不大,我认为这更像是为了使用 hooks 而强行引入 hooks。

具体实现代码 :github.com/lwj1994/sta...

使用文档

Flutter State Observer

使用 Observer 模式解决状态复用问题的 Flutter 包。

特性

  • LifecycleObserver: 用于创建可复用状态观察者的基类。
  • LifecycleObserverMixin : 用于在 State 中管理观察者生命周期的 mixin。
  • 常用观察者 :
    • AnimControllerObserver: 可复用的 AnimationController 逻辑。
    • ScrollControllerObserver: 管理 ScrollController
    • TabControllerObserver: 管理 TabController
    • TextEditingControllerObserver: 管理 TextEditingController

用法

自定义观察者

你可以通过继承 LifecycleObserver 轻松创建自己的观察者。

示例:一个 UserDataObserver,它能够:

  1. onInit 中初始化数据获取。
  2. onUpdate 中当 userId 变化时重新获取数据。
  3. onBuild 中记录调试信息。
dart 复制代码
import 'package:flutter/material.dart';
import 'package:state_lifecycle_observer/state_lifecycle_observer.dart';

class Data {
  final String id;
  final String info;
  Data(this.id, this.info);
}

class UserDataObserver extends LifecycleObserver<ValueNotifier<Data?>> {
  // 获取 Widget 最新参数的机制
  final String Function() getUserId;
  
  // 用于追踪变化的内部状态
  late String _currentUserId;

  UserDataObserver(
    super.state, {
    required this.getUserId,
  });

  @override
  void onInit() {
    target = ValueNotifier(null);
    _currentUserId = getUserId();
    _fetchData(_currentUserId);
  }

  @override
  void onUpdate() {
    // 检查依赖 (userId) 是否发生变化
    final newUserId = getUserId();
    if (newUserId != _currentUserId) {
      debugPrint('UserId changed from $_currentUserId to $newUserId');
      _currentUserId = newUserId;
      _fetchData(_currentUserId);
    }
  }

  @override
  void onBuild(BuildContext context) {
    debugPrint('Building with user: $_currentUserId');
  }

  @override
  void onDispose() {
    target.dispose();
  }

  void _fetchData(String id) async {
    // 模拟网络请求
    await Future.delayed(const Duration(milliseconds: 500));
    if (_currentUserId == id) { // 避免竞态条件
      target.value = Data(id, 'Info for $id');
    }
  }
}

与 flutter_hooks 的比较

特性 state_lifecycle_observer flutter_hooks
范式 OOP (类) 函数式 (Hooks)
基类 标准 StatefulWidget HookWidget
生命周期 显式 (onInit, onDispose) 隐式 (useEffect)
学习曲线 低 (标准 Flutter) 中 (Hooks 规则)
黑魔法 低 (Mixin + List) 高 (Element 逻辑)
条件逻辑 随处支持 不允许在 build 中使用
相关推荐
子春一1 小时前
Flutter for OpenHarmony:色彩捕手:基于 CIELAB 色差模型与人眼感知的高保真色彩匹配游戏架构解析
flutter·游戏·架构
ZH15455891311 小时前
Flutter for OpenHarmony Python学习助手实战:数据库操作与管理的实现
python·学习·flutter
Lionel6892 小时前
Flutter 鸿蒙:获取真实轮播图API数据
flutter
千逐682 小时前
《基于 Flutter for OpenHarmony 的沉浸式天气可视化系统设计与实现》
flutter
一只大侠的侠2 小时前
Flutter开源鸿蒙跨平台训练营 Day8获取轮播图网络数据并实现展示
flutter·开源·harmonyos
sugar_hang2 小时前
Flutter 中的 TCP
flutter
子春一4 小时前
Flutter for OpenHarmony:形状拼图:基于路径几何与空间吸附的交互式拼图系统架构解析
flutter·系统架构
ujainu14 小时前
Flutter + OpenHarmony 游戏开发进阶:用户输入响应——GestureDetector 实现点击发射
flutter·游戏·openharmony
hudawei99614 小时前
TweenAnimationBuilder和AnimatedBuilder两种动画的比较
flutter·ui·动画·tweenanimation·animatedbuilder
ujainu14 小时前
Flutter + OpenHarmony 实现无限跑酷游戏开发实战—— 对象池化、性能优化与流畅控制
flutter·游戏·性能优化·openharmony·endless runner