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 中使用
相关推荐
忆江南12 小时前
iOS 深度解析
flutter·ios
明君8799712 小时前
Flutter 实现 AI 聊天页面 —— 记一次 Markdown 数学公式显示的踩坑之旅
前端·flutter
恋猫de小郭13 小时前
移动端开发稳了?AI 目前还无法取代客户端开发,小红书的论文告诉你数据
前端·flutter·ai编程
MakeZero16 小时前
Flutter那些事-交互式组件
flutter
shankss16 小时前
pull_to_refresh_simple
flutter
shankss16 小时前
Flutter 下拉刷新库新特性:智能预加载 (enableSmartPreload) 详解
flutter
SoaringHeart2 天前
Flutter调试组件:打印任意组件尺寸位置信息 NRenderBox
前端·flutter
九狼3 天前
Flutter URL Scheme 跨平台跳转
人工智能·flutter·github
_squirrel3 天前
记录一次 Flutter 升级遇到的问题
flutter
Haha_bj3 天前
Flutter——状态管理 Provider 详解
flutter·app