当前位置: 首页 > news >正文

分享网站制作天元建设集团有限公司恒大

分享网站制作,天元建设集团有限公司恒大,什么网站容易收录,前后端分离实现网站开发一、riverpod状态管理中所涉及到的widget UI组件对比分析UI 组件状态类型语法形式特点ConsumerWidget有状态无状态形式最常用#xff0c;通过WidgetRef访问provider#xff0c;所谓无状态#xff0c;是指ConsumerWidegt不像StatefulWidegt那样创建state,在它内部不可以定义状…一、riverpod状态管理中所涉及到的widget UI组件对比分析UI 组件状态类型语法形式特点ConsumerWidget有状态无状态形式最常用通过WidgetRef访问provider所谓无状态是指ConsumerWidegt不像StatefulWidegt那样创建state,在它内部不可以定义状态变量然后再调用setState()更新状态和UI,类似于statelessWidget但是可以在它内部引用外部的或全局状态提供者provider以达到全局状态提供者状态更新时ConsumerWidget也重新构建UIConsumerStatefulWidget有状态有状态形式具有完整生命周期可管理内部状态,类似于StatefulWidget,创建状态重载createState()初始化状态重截initState()状态销毁重载dispose()Consumer有状态 ---局部UI重建只重建部分UI优化性能ProviderScope有状态 ---创建新的provider作用域可覆盖父级providerHookWidget有状态无状态形式使用 Hooks(钩子)依赖flutter_hooks这个库使用useState在无状态Widget中管理状态和其他副作用生命周期使用useEffectHookConsumerWidget有状态无状态形式可以同时使用 Hooks Riverpod管理状态生命周期使用useEffect下面用代码分析比较一下使用场景1. ConsumerWidget - 最常用的UI组件 final counterProvider StateProviderint((ref) 0);class ConsumerWidgetExample extends ConsumerWidget {const ConsumerWidgetExample({super.key});overrideWidget build(BuildContext context, WidgetRef ref) {final counter ref.watch(counterProvider);return Card(child: Padding(padding: const EdgeInsets.all(16.0),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [const Text(1. ConsumerWidget,style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),),const SizedBox(height: 10),Text(这是一个无状态组件通过WidgetRef访问provider),const SizedBox(height: 10),Text(计数器: $counter, style: const TextStyle(fontSize: 20)),const SizedBox(height: 10),ElevatedButton(onPressed: () ref.read(counterProvider.notifier).state,child: const Text(增加计数),),],),),);} } 2. ConsumerStatefulWidget - 需要内部状态的UI组件 final counterProvider StateProviderint((ref) 0);class ConsumerStatefulWidgetExample extends ConsumerStatefulWidget {const ConsumerStatefulWidgetExample({super.key});overrideConsumerStateConsumerStatefulWidgetExample createState() _ConsumerStatefulWidgetExampleState(); }class _ConsumerStatefulWidgetExampleState extends ConsumerStateConsumerStatefulWidgetExample {int _localClicks 0;overridevoid initState() {super.initState();debugPrint(ConsumerStatefulWidget 初始化);}overridevoid dispose() {debugPrint(ConsumerStatefulWidget 被销毁);super.dispose();}overrideWidget build(BuildContext context) {final counter ref.watch(counterProvider);return Card(child: Padding(padding: const EdgeInsets.all(16.0),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [const Text(2. ConsumerStatefulWidget,style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),),const SizedBox(height: 10),Text(这是一个有状态组件可以管理内部状态),const SizedBox(height: 10),Text(全局计数器: $counter, style: const TextStyle(fontSize: 16)),Text(本地点击次数: $_localClicks, style: const TextStyle(fontSize: 16)),const SizedBox(height: 10),Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [ElevatedButton(onPressed: () {ref.read(counterProvider.notifier).state;},child: const Text(全局1),),ElevatedButton(onPressed: () {setState(() {_localClicks;});},child: const Text(本地1),),],),],),),);} } 3. Consumer - 用于局部UI重建 final counterProvider StateProviderint((ref) 0);class ConsumerExample extends ConsumerWidget {const ConsumerExample({super.key});overrideWidget build(BuildContext context, WidgetRef ref) {return Card(child: Padding(padding: const EdgeInsets.all(16.0),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [const Text(3. Consumer,style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),),const SizedBox(height: 10),const Text(使用Consumer只重建UI的特定部分:),const SizedBox(height: 10),// 这个Text不会在计数器变化时重建const Text(这是静态文本不会重建),const SizedBox(height: 10),// 只有Consumer内的部分会在计数器变化时重建Consumer(builder: (context, ref, child) {final counter ref.watch(counterProvider);return Text(动态计数: $counter,style: const TextStyle(fontSize: 20, color: Colors.blue),);},),const SizedBox(height: 10),ElevatedButton(onPressed: () ref.read(counterProvider.notifier).state,child: const Text(增加计数),),],),),);} } 4. ProviderScope - 用于创建新的provider作用域    ProviderScope示例1 final counterProvider StateProviderint((ref) 0);class ProviderScopeExample extends StatelessWidget {const ProviderScopeExample({super.key});overrideWidget build(BuildContext context) {// 创建一个新的provider作用域可以覆盖父级的providerreturn ProviderScope(child: Card(child: Padding(padding: const EdgeInsets.all(16.0),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [const Text(4. ProviderScope,style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),),const SizedBox(height: 10),const Text(创建一个新的provider作用域),const SizedBox(height: 10),// 在这个作用域内可以覆盖父级的providerConsumer(builder: (context, ref, child) {final counter ref.watch(counterProvider);return Text(计数器: $counter);},),],),),),);} } ProviderScope示例2:当我们有一个ListView显示产品列表每个项目都需要知道正确的产品ID或索引时 class ProductItem extends StatelessWidget {const ProductItem({super.key, required this.index});final int index;overrideWidget build(BuildContext context) {// do something with the index}}class ProductList extends StatelessWidget {overrideWidget build(BuildContext context) {return ListView.builder(itemBuilder: (_, index) ProductItem(index: index),);}}在上面的代码中我们将构建器的索引作为构造函数参数传递给 ProductItem 小部件,这种方法有效但如果ListView重新构建它的所有子项也将重新构建。作为替代方法我们可以在嵌套的ProviderScope内部覆盖Provider的值 // 1. Declare a Providerfinal currentProductIndex Providerint((_) throw UnimplementedError());class ProductList extends StatelessWidget {overrideWidget build(BuildContext context) {return ListView.builder(itemBuilder: (context, index) {// 2. Add a parent ProviderScopereturn ProviderScope(overrides: [// 3. Add a dependency override on the indexcurrentProductIndex.overrideWithValue(index),],// 4. return a **const** ProductItem with no constructor argumentschild: const ProductItem(),);});}}class ProductItem extends ConsumerWidget {const ProductItem({super.key});overrideWidget build(BuildContext context, WidgetRef ref) {// 5. Access the index via WidgetReffinal index ref.watch(currentProductIndex);// do something with the index}}在这种情况下我们创建一个默认抛出UnimplementedError的Provider。通过将父ProviderScope添加到ProductItem小部件来覆盖其值。我们在ProductItem的build方法中监视索引。这对性能更有益因为我们可以将ProductItem作为const小部件创建在ListView.builder中。因此即使ListView重新构建除非其索引发生更改否则我们的ProductItem将不会重新构建。5. HookWidget - 利用hooks钩子在无状态下管理状态假设你有一个计数器应用你使用useState来管理计数值 import package:flutter/material.dart; import package:flutter_hooks/flutter_hooks.dart;class HookWidgetExample extends HookWidget {const HookWidgetExample({super.key});overrideWidget build(BuildContext context) {// 使用 useState Hook 来管理状态final counter useState(0);// 使用 useEffect Hook 处理副作用useEffect(() {debugPrint(HookWidget 初始化或计数器变化: ${counter.value});return () debugPrint(HookWidget 清理效果);}, [counter.value]);// 使用 useMemoized 缓存计算结果final doubledValue useMemoized(() {return counter.value * 2;}, [counter.value]);return Card(child: Padding(padding: const EdgeInsets.all(16.0),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [const Text(1. HookWidget,style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),),const SizedBox(height: 10),const Text(表面上是无状态组件但实际上是有状态的),const SizedBox(height: 10),Text(计数器: ${counter.value}),Text(双倍值: $doubledValue),const SizedBox(height: 10),ElevatedButton(onPressed: () counter.value,child: const Text(增加计数),),],),),);} } 6. HookConsumerWidget - 结合 Hooks 和 Riverpod class HookConsumerWidgetExample extends HookConsumerWidget {const HookConsumerWidgetExample({super.key});overrideWidget build(BuildContext context, WidgetRef ref) {// 使用 Hooks 管理本地状态final localCounter useState(0);final animationController useAnimationController(duration: const Duration(milliseconds: 500),);// 使用 Riverpod 管理全局状态final globalCounter ref.watch(counterProvider);// 使用 useEffect 处理副作用useEffect(() {debugPrint(本地计数器变化: ${localCounter.value});return null;}, [localCounter.value]);return Card(child: Padding(padding: const EdgeInsets.all(16.0),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [const Text(2. HookConsumerWidget,style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),),const SizedBox(height: 10),const Text(结合了 Hooks 和 Riverpod 的强大功能),const SizedBox(height: 10),Text(本地计数器: ${localCounter.value}),Text(全局计数器: $globalCounter),const SizedBox(height: 10),Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [ElevatedButton(onPressed: () localCounter.value,child: const Text(本地1),),ElevatedButton(onPressed: () ref.read(counterProvider.notifier).state,child: const Text(全局1),),],),],),),);} }
http://www.pierceye.com/news/988384/

相关文章:

  • 网站关键词怎么填写南昌网站建设一般多少钱一年
  • 公司网站制作费用无区域公司注册要求
  • 网站文章更新时间去国外做外卖网站好
  • 北京网站制作设计wordpress seo 介绍
  • 手机网站搭建平台怎么查网站域名备案
  • 用文件传输协议登录网站网站开发设计手册
  • 有什么兼职做it的网站网络推广怎么做才有效
  • 网站后台开发教程沈阳网站制作流程
  • 可以自己做课程的网站深圳小型网站建设
  • 静安做网站公司网站上线的通知
  • 怎么建设电影网站wordpress 附件上传插件下载
  • 网站导航内链建设企业网站设计方式有哪些
  • 手表网站建站千秋网络是家西安做网站的公司
  • 济南企业网站百度seo优化是做什么的
  • 网站颜色搭配案例wordpress洛米主题
  • 网站几个关键词网站备案为什么要关闭
  • 深圳网站制作哪家便宜怎么利用百度云盘做网站
  • 美容培训东莞网站建设做的网站上更改内容改怎么回事
  • 绵阳新农网的网站是哪个公司做的wordpress 在线教育主题
  • 大连优化网站怎样制作企业的网站
  • 网站建设邀请函北京网站优化 卓立海创
  • 公司后台的网站代理维护更新商贸有限公司注销流程
  • 网站建设工作动态wordpress次元主题
  • 手机网站源码asp网站快速排名技巧
  • 站点怎么建网页宁波网站建设设计制作公司
  • 黑龙江企业网站建设网站模板带后台 下载
  • 徐州在线制作网站营销网络是什么意思
  • 上海网站建设seo公司微信小程序制作教学
  • 信息化工作总结 网站建设十堰市有几家网站公司
  • 宠物网站建站目标做外贸的网站哪些是最好的