拆分跨端大组件要从稳定边界开始
拆分跨端大组件要从稳定边界开始
一个 widget 既请求数据、处理路由、维持动画又拼界面,重构时最怕大刀阔斧。先抽出没有状态、输入输出明确的叶子组件,再移动局部状态,最后才碰页面协调逻辑。每一步都能运行和回退。
class ProductTitle extends StatelessWidget {
const ProductTitle({super.key, required this.title});
final String title;
@override
Widget build(BuildContext context) => Text(title, style: Theme.of(context).textTheme.titleLarge);
}
动画控制器应由真正拥有生命周期的 State 创建和释放,不要把 controller 透传到无关层级。静态分析可以提示复杂度和未释放资源,但不能替代实际交互测试。重构完成后覆盖加载、失败、空数据和返回页面,确认结构变化没有改掉用户看得见的行为。
先画出状态和依赖的归属
开始拆之前,我会列出这个页面持有哪些状态:服务端数据、输入草稿、选中项、一次性的动画和路由参数。不同来源的状态不该因为都在同一个文件里就绑在一起。展示组件只接收它需要的值和回调,真正协调请求、缓存与跳转的部分留在页面层。这样抽取时不会为了传一个布尔值,把整段业务对象层层带下去。
如果子组件需要处理异步状态,也要把加载、错误和空结果当作输入的一部分。只传成功数据会让组件在边界状态又回到父页面里堆条件判断。名称可以朴素些,例如 ProductList、ProductListLoading,重点是调用处一眼能看出当前分支,而不是追求抽象名词。
每次移动后都验证回退路径
拆分顺序应当允许中途停止。先新增组件并由旧页面调用,再删除原来的重复结构;不要在一次提交里同时改状态管理、主题和导航。提交记录清楚,出现手势失效或焦点丢失时才找得到责任边界。
尤其要检查返回页面后的状态:列表位置是否保留,未提交的输入是否按产品规则处理,动画是否还在后台跑。大组件往往把这些细节偶然维持住,拆开后必须明确谁负责。重构的成果不只是文件变小,更是页面生命周期不再靠隐含顺序支撑。
让组件 API 保持朴素
抽出来的组件不必立刻支持所有变体。先提供当前页面已经验证过的属性,重复出现的需求再上提为通用能力。过早暴露大量可选参数,会把原来一个大组件的复杂度搬到调用处,调用者也不知道哪些组合是被支持的。
设计系统中的组件尤其要区分内容插槽和业务判断。标题、图标、空状态文案可以由调用方提供;是否有权限、请求该不该重试则留在业务层。这个边界清楚后,组件在其他页面复用时不会偷偷带上原来的产品规则,也不需要依赖特定路由才能工作。
用真实流程检验拆分结果
组件测试覆盖单个输入输出,页面测试覆盖它们如何协作。除了正常进入,还要模拟网络慢、返回重进、数据刷新和连续点击。这样能发现拆分后状态被重复创建、回调顺序改变或加载提示闪烁的问题。没有必要为每个内部方法写一套脆弱断言,优先验证用户完成任务时看到的结果。
重构过程中若发现原页面的规则说不清,不要用组件层的默认值悄悄补齐。把选择交还给页面或产品讨论,明确后再沉淀为公共约定。清晰的边界会暴露问题,这正是拆分值得做的原因。
更多推荐




所有评论(0)