You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取Riverpod 2中Map类型状态下指定列表的长度?

问题解决:Riverpod Map状态访问与更新错误

核心问题分析

  1. Provider类型错误:用StateProvider承载Notifier实例不符合Riverpod设计规范,Notifier子类需搭配NotifierProvider使用。
  2. 状态更新逻辑错误:直接修改Map/List这类可变对象的内部元素(比如state[martialArtsMove] = items或clear()),Riverpod无法检测到状态引用变化,导致UI不更新。
  3. 状态访问方式错误:页面中错误尝试访问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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 03:16:32