在这里插入图片描述
在这里插入图片描述

子玥酱 (掘金 / 知乎 / CSDN / 简书 同名)

大家好,我是 子玥酱,一名长期深耕在一线的前端程序媛 👩‍💻。曾就职于多家知名互联网大厂,目前在某国企负责前端软件研发相关工作,主要聚焦于业务型系统的工程化建设与长期维护。

我持续输出和沉淀前端领域的实战经验,日常关注并分享的技术方向包括 前端工程化、小程序、React / RN、Flutter、跨端方案
在复杂业务落地、组件抽象、性能优化以及多端协作方面积累了大量真实项目经验。

技术方向:前端 / 跨端 / 小程序 / 移动端工程化
内容平台:
掘金、知乎、CSDN、简书
创作特点:
实战导向、源码拆解、少空谈多落地
文章状态:
长期稳定更新,大量原创输出

我的内容主要围绕 前端技术实战、真实业务踩坑总结、框架与方案选型思考、行业趋势解读 展开。文章不会停留在“API 怎么用”,而是更关注为什么这么设计、在什么场景下容易踩坑、真实项目中如何取舍,希望能帮你在实际工作中少走弯路。

子玥酱 · 前端成长记录官 ✨
👋 如果你正在做前端,或准备长期走前端这条路
📚 关注我,第一时间获取前端行业趋势与实践总结
🎁 可领取 11 类前端进阶学习资源(工程化 / 框架 / 跨端 / 面试 / 架构)
💡 一起把技术学“明白”,也用“到位”

持续写作,持续进阶。
愿我们都能在代码和生活里,走得更稳一点 🌱

引言

很多团队在引入 Flutter 时,第一批主力往往来自前端或 RN。

结果也很典型:

  • 短期推进极快
  • 中期开始状态失控
  • 后期频繁出现「这状态到底该放哪」的争论

于是一个问题反复出现:

前端经验,在 Flutter 里到底是资产,还是负债?

答案是:一半是加分,一半是结构性陷阱。

关键不在「有没有前端经验」,而在哪些经验被无条件带了进来

前端经验真正加分的地方,其实很少

先说结论:前端经验在 Flutter 里真正稳稳加分的,集中在 3 件事上。

对“不可变数据 + 单向流”的天然接受度

写过 Redux / MobX / Vuex / Zustand 的人,对这件事并不陌生:

  • 状态是数据,不是行为
  • UI 是状态的投影
  • 修改路径要清晰

这在 Flutter 里,天然适配:

class ProfileState {
  final String name;
  final bool loading;

  ProfileState({required this.name, required this.loading});

  ProfileState copyWith({String? name, bool? loading}) {
    return ProfileState(
      name: name ?? this.name,
      loading: loading ?? this.loading,
    );
  }
}

这类写法,前端出身的人心理负担极低

对“副作用需要被隔离”的直觉

前端开发者通常对这些事情比较敏感:

  • 请求不该直接写在 render / build
  • 定时器、订阅、监听必须有生命周期
  • 不能在 UI 层偷偷改状态

这在 Flutter 里非常重要:


void initState() {
  super.initState();
  context.read(profileProvider.notifier).load();
}

而不是:

Widget build(BuildContext context) {
  // ❌ build 里发请求
  fetchProfile();
}

这类错误,前端背景的人反而更少犯。

对组件边界和复用的敏感度

前端习惯:

  • 组件有明确输入
  • 组件尽量无副作用
  • 不依赖“外部魔法状态”

在 Flutter 中,这意味着:

class UserHeader extends StatelessWidget {
  final User user;

  const UserHeader({required this.user});

  
  Widget build(BuildContext context) {
    ...
  }
}

而不是:

class UserHeader extends StatelessWidget {
  
  Widget build(BuildContext context) {
    final user = context.read(userProvider);
    ...
  }
}

这一步,对长期维护至关重要

真正的坑,来自「前端经验的惯性」

问题不是前端经验本身,而是**“默认迁移”**。

把 Flutter 当成“另一个 React”

这是最危险的一点。常见心理模型是:

Widget ≈ Component
Provider ≈ Store
rebuild ≈ re-render

然后下意识就会做这些事:

  • 状态往上提
  • Provider 套 Provider
  • 一个页面一个 Store
  • 页面卸载不重要,反正“会重建”

结果就是:

  • 状态作用域失真
  • rebuild 影响面不可控
  • Provider 生命周期与页面生命周期脱节

对“页面常驻”的低估

在 Web / RN 里:

  • 页面卸载是常态
  • 状态销毁非常自然

但 Flutter 里:

  • Tab 页常驻
  • PageView 常驻
  • Navigator 栈里的页面可能长期存在

于是前端习惯的:

// 页面卸载,状态自然消失

在 Flutter 里变成了:

// 页面没销毁,状态一直活着

状态开始“自然膨胀”,但没人察觉。

把“方便访问”误认为“合理归属”

前端里常见思路是:

这个状态很多地方要用,那就放全局

迁移到 Flutter 后就变成:

final selectedItemProvider = StateProvider<Item?>((ref) => null);

结果:

  • 一个“当前选中项”
  • 被列表页、详情页、弹窗、浮层同时依赖
  • 生命周期不清晰
  • 修改来源不可追溯

这就是典型的伪全局状态

前端经验最容易带来的 3 个结构性误判

误判一:状态是“共享资源”,而不是“生命周期资源”

前端更习惯“共享”,Flutter 更强调“活多久”。

在 Flutter 中,一个状态最重要的问题是:

它应该活到什么时候?

而不是:

有多少地方用?

误判二:Provider 是状态仓库,而不是作用域工具

很多前端背景的 Flutter 项目:

MultiProvider(
  providers: [
    ChangeNotifierProvider(create: (_) => PageAState()),
    ChangeNotifierProvider(create: (_) => PageBState()),
    ChangeNotifierProvider(create: (_) => PageCState()),
  ],
  child: App(),
)

这在前端里看起来很合理,在 Flutter 里却意味着:

  • 页面状态被强行提升到 App 级
  • 生命周期彻底错位
  • 重构成本指数级上升

误判三:状态重构 = 改数据结构

前端里,重构状态往往只是:

  • 拆 reducer
  • 调整 store
  • 重命名字段

但在 Flutter 中,状态绑定了:

  • Widget 树
  • 生命周期
  • rebuild 范围
  • Provider 注入层级

中途推倒,代价极高。

真正成熟的做法:前端经验要“翻译”,不能“照搬”

一个经验判断标准很简单:

这个经验,是否考虑了 Widget 生命周期?

需要“翻译”的前端经验

前端思路 Flutter 中的正确版本
状态集中管理 状态按生命周期分层
全局 store 明确的作用域 Provider
页面卸载即清理 显式 dispose / autoDispose
组件无状态 Widget 无状态 ≠ 没有状态

结论:前端经验是利器,但不是底座

可以非常明确地说一句:

前端经验在 Flutter 里,是“战术优势”,不是“架构答案”。

  • 加分的,是对数据流、不可变性、组件化的理解
  • 致命的,是对生命周期、常驻页面、状态归属的误判

真正成熟的 Flutter 团队,往往会出现一个阶段:

主动“反前端直觉”,重新理解状态。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐