如何获取Riverpod 2中Map类型状态下指定列表的长度?
问题解决:Riverpod Map状态访问与更新错误
核心问题分析
- Provider类型错误:用
StateProvider承载Notifier实例不符合Riverpod设计规范,Notifier子类需搭配NotifierProvider使用。 - 状态更新逻辑错误:直接修改Map/List这类可变对象的内部元素(比如
state[martialArtsMove] = items或clear()),Riverpod无法检测到状态引用变化,导致UI不更新。 - 状态访问方式错误:页面中错误尝试访问Notifier实例的
state属性,正确做法是通过NotifierProvider直接获取状态值。
修改后的完整代码
Provider定义
import 'package:flutter_riverpod/flutter_riverpod.dart'; enum MartialArtsMove { hand, kick, grab; } class OneSteps extends Notifier<Map<MartialArtsMove, List<num>>> { @override Map<MartialArtsMove, List<num>> build() => {for (final k in MartialArtsMove.values) k: <num>[]}; void setMove(MartialArtsMove martialArtsMove, List<num> items) { // 创建新Map替换原有状态,触发Riverpod更新 state = {...state, martialArtsMove: List.from(items)}; } void clearAll() { // 生成全新的空列表Map,确保状态引用变化 state = {for (final k in MartialArtsMove.values) k: <num>[]}; } } // 使用NotifierProvider关联Notifier与状态类型 final oneStepsProvider = NotifierProvider<OneSteps, Map<MartialArtsMove, List<num>>>(OneSteps.new);
页面使用代码
final oneStepState = ref.watch(oneStepsProvider); Text( 'Hands ${oneStepState[MartialArtsMove.hand]!.length}', textAlign: TextAlign.center, style: const TextStyle(fontSize: 14), )
关键说明
NotifierProvider直接暴露Notifier的状态值(即你的Map),而非Notifier实例,页面中ref.watch得到的就是Map对象。- 必须通过生成新的Map/List实例来更新状态,Riverpod通过引用变化判断状态是否更新,直接修改原有对象内部数据不会触发UI刷新。
- 修改
state变量后,Riverpod会自动通知所有监听者,无需手动调用ref.notifyListeners()。
内容的提问来源于stack exchange,提问作者hcker2000
相关产品推荐
相关产品推荐

