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

Riverpod状态变更方法未按预期更新状态问题排查

问题排查与修复方案

1. 数据库日期匹配问题(核心原因)

问题点

  • 插入数据时日期赋值错误:insertSet方法里误用了比较运算符==而非赋值运算符=,导致插入的date字段未被设置为yyyy-MM-dd格式字符串,而是使用数据库默认的CURRENT_TIMESTAMP(格式为yyyy-MM-dd HH:mm:ss)。
  • 查询条件不匹配:getTodayItems方法用yyyy-MM-dd格式字符串匹配带时间戳的date字段,自然查不到数据,最终状态变为空列表。

修复代码

修改SQLHelper的insertSet方法:

static Future<int> insertSet(Set set) async {
  final db = await SQLHelper.db();
  DateTime now = DateTime.now();
  String formattedDate = DateFormat('yyyy-MM-dd').format(now);
  // 修正为赋值运算符
  set.date = formattedDate;

  final id = await db.insert('sets', set.toJson(),
      conflictAlgorithm: sql.ConflictAlgorithm.replace);
  return id;
}

若需保留时间戳信息,可修改查询语句匹配日期部分:

static Future<List<Map<String, dynamic>>> getTodayItems() async {
  final db = await SQLHelper.db();
  DateTime now = DateTime.now();
  String formattedDate = DateFormat('yyyy-MM-dd').format(now);
  // 使用LIKE匹配日期前缀
  final results = await db.rawQuery(
      'SELECT * FROM sets WHERE date LIKE ?', 
      ['$formattedDate%']
  );
  print(results);
  return results;
}

2. getTodayItems方法缺少await

原方法调用db.rawQuery时未加await,导致返回未完成的Future,无法获取实际查询结果。修复后加上await:

static Future<List<Map<String, dynamic>>> getTodayItems() async {
  final db = await SQLHelper.db();
  DateTime now = DateTime.now();
  String formattedDate = DateFormat('yyyy-MM-dd').format(now);
  // 加上await获取实际查询结果
  final results = await db.rawQuery(
      'SELECT * FROM sets WHERE date = ?', 
      [formattedDate]
  );
  print(results);
  return results;
}

3. ListView构建时的错误调用

在ListView.builder的itemBuilder中调用getTodaySets()会导致每个item构建时都触发查询,造成无限刷新和性能浪费,且状态更新时机混乱。

修复方案

将getTodaySets()移到页面初始化时调用,例如在HookWidget中使用useEffect:

// 页面初始化时加载今日数据
useEffect(() {
  ref.read(setsProviderProvider.notifier).getTodaySets();
  return null;
}, []);

// ListView仅负责渲染
child: ListView.builder(
  scrollDirection: Axis.vertical,
  shrinkWrap: true,
  itemCount: ref.watch(setsProviderProvider).length,
  itemBuilder: ((_, index) {
    final list = ref.watch(setsProviderProvider);
    var set = list[index];
    return ListTile(
      title: Text(set.exerciseName.toString()),
      subtitle: Column(
        children: [
          Text(set.totalWeight.toString()),
          Text(set.totalReps.toString()),
        ],
      ),
    );
  }),
),

4. 额外建议:状态初始化自动加载数据

可在SetsProvider的build方法中自动加载数据,避免手动调用时机问题:

@riverpod
class SetsProvider extends _$SetsProvider {
  @override
  List<Set> build() {
    // 初始化时自动加载今日数据
    getTodaySets();
    return [];
  }

  // 其他方法不变
}

内容的提问来源于stack exchange,提问作者JOHN436456

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 03:45:29