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

Riverpod的StateNotifier更新状态时如何获取更新前的旧状态

解决方案

步骤1:调整CitiesState类,新增copyWith方法

建议将属性改为final符合Riverpod不可变状态的设计规范,copyWith是Dart生态中处理不可变对象部分更新的常用方案:

import 'package:flutter_riverpod/flutter_riverpod.dart';

class CitiesState {
  final List<String> cities;
  final String selectedCity;

  CitiesState({required this.cities, required this.selectedCity});

  // 新增copyWith方法,未传入的属性默认复用旧值
  CitiesState copyWith({
    List<String>? cities,
    String? selectedCity,
  }) {
    return CitiesState(
      cities: cities ?? this.cities,
      selectedCity: selectedCity ?? this.selectedCity,
    );
  }
}

步骤2:修改updateCitiesData方法,保留旧的选中城市值

可以通过state.whenOrNull安全读取不同状态下的旧值,容错性更高:

class ChooseCityPageModel extends StateNotifier<AsyncValue<CitiesState>> {
  ChooseCityPageModel() : super(AsyncValue.loading());

  Future<void> updateCitiesData() async {
    // 先读取旧状态的selectedCity,拿不到则用默认值
    final oldSelectedCity = state.whenOrNull(
          data: (stateData) => stateData.selectedCity,
        ) ?? "New York";

    state = const AsyncValue.loading();

    try {
      final latestCities = await myAPI.getAvailableCities();
      state = AsyncValue.data(
        CitiesState(
          selectedCity: oldSelectedCity,
          cities: latestCities,
        ),
      );
      // 用copyWith的写法更简洁,效果完全一致:
      // state.whenOrNull(data: (oldState) {
      //   state = AsyncValue.data(oldState.copyWith(cities: latestCities));
      // });
    } catch (error, stackTrace) {
      // 新版本Riverpod要求AsyncValue.error传入堆栈追踪参数
      state = AsyncValue.error(error, stackTrace);
    }
  }
}

注意事项

  • 你原代码中创建状态实例时类名写错了,你定义的状态类是CitiesState,不要写成ChooseCityPageState
  • 后续如果需要单独修改选中城市,也可以直接用copyWith实现:state = AsyncValue.data(state.value!.copyWith(selectedCity: '上海'))
  • 如果能确定调用更新方法时一定有成功加载的旧状态,也可以直接用state.value?.selectedCity读取旧值,和whenOrNull写法效果一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 01:54:03