//should_rebuild_widget library should_rebuild_widget; import 'package:flutter/material.dart'; typedef ShouldRebuildFunction<T> = bool Function(T oldWidget, T newWidget); class ShouldRebuild<T extends Widget> extends StatefulWidget { final T child; final ShouldRebuildFunction<T>? shouldRebuild; const ShouldRebuild({required this.child, this.shouldRebuild}); @override ShouldRebuildState createState() => ShouldRebuildState<T>(); } class ShouldRebuildState<T extends Widget> extends State<ShouldRebuild> { @override ShouldRebuild<T> get widget => super.widget as ShouldRebuild<T>; T? oldWidget; @override Widget build(BuildContext context) { final T newWidget = widget.child; if (oldWidget == null || (widget.shouldRebuild == null ? true : widget.shouldRebuild!(oldWidget!, newWidget))) { oldWidget = newWidget; } return oldWidget as T; } }
基本原理: 根据传入的 shouldRebuild
方法判定返回新或者旧组件
使用方法如下:
ShouldRebuild<VerifyCode>( shouldRebuild: (oldWidget, newWidget) =>oldWidget.dotCount != newWidget.dotCount, child: VerifyCode(onChanged: _loginController.getVerifyCode), ),
使用 const声明的组件
使用 const 声明的组件不会更新,其源码如下
Element updateChild(Element child, Widget newWidget, dynamic newSlot) { ... if (child.widget == newWidget) { if (child.slot != newSlot) // 如果新旧组件不相同就update updateSlotForChild(child, newSlot); return child; // 相同就直接返回child } if (Widget.canUpdate(child.widget, newWidget)) { if (child.slot != newSlot) updateSlotForChild(child, newSlot); child.update(newWidget); assert(child.widget == newWidget); assert(() { child.owner._debugElementWasRebuilt(child); return true; }()); return child; } ... }