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

Flutter Riverpod 2中如何用AsyncNotifier实现删除并本地刷新页面

问题

项目中有两个AsyncNotifier(及对应Provider):

  • 一个是从REST API获取待办事项列表的AsyncNotifier<List>
  • 另一个是按ID删除待办事项的AsyncNotifier

在展示待办列表的页面/组件中监听删除待办的Notifier,点击删除按钮后显示成功/失败的SnackBar。相关代码如下:

构建方法中的监听与列表获取:

ref.listen<AsyncValue<void>>(
  deleteTodoControllerProvider,
  (_, state) => state.whenOrNull(
    error: (error, stackTrace) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(error.toString())),
      );
    },
  ),
);
final todoList = ref.watch(todoListControllerProvider);

删除按钮的onPressed方法:

ref.read(deleteTodoControllerProvider.notifier).deleteTodoById(todo.id!);

需求:删除待办后不重新调用API,通过本地更新列表状态(如removeWhere)刷新页面。尝试调用todoListProvider.invalidate()会触发重复API请求,询问在待办列表Notifier中添加方法修改状态是否可行?

解决方案

完全可行,这是处理本地状态更新的合理方案,具体实现步骤如下:

  1. 在列表Notifier中添加本地更新方法
    在负责待办列表的AsyncNotifier<List<Todo>>里新增一个方法,用于从本地状态中移除指定ID的待办:
class TodoListNotifier extends AsyncNotifier<List<Todo>> {
  @override
  FutureOr<List<Todo>> build() async {
    // 初始从API获取列表的逻辑
    return await fetchTodosFromApi();
  }

  // 新增本地移除待办的方法
  void removeTodoLocally(String todoId) {
    final currentList = state.value;
    if (currentList != null) {
      // 创建新列表(遵循不可变状态原则),移除目标ID的待办
      final updatedList = currentList.where((todo) => todo.id != todoId).toList();
      // 更新状态为新的AsyncData包裹的列表
      state = AsyncData(updatedList);
    }
  }
}
  1. 修改删除Notifier的逻辑,成功后触发本地更新
    在DeleteTodoNotifier的删除方法中,当API请求成功后,调用列表Notifier的本地更新方法:
class DeleteTodoNotifier extends AsyncNotifier<void> {
  @override
  FutureOr<void> build() {}

  Future<void> deleteTodoById(String todoId) async {
    state = const AsyncLoading();
    try {
      // 调用API执行删除操作
      await api.deleteTodo(todoId);
      state = const AsyncData(null);
      // 删除成功后,触发列表的本地状态更新
      ref.read(todoListControllerProvider.notifier).removeTodoLocally(todoId);
    } catch (e, stackTrace) {
      state = AsyncError(e, stackTrace);
    }
  }
}
  1. 保留原有错误提示逻辑
    你原来的ref.listen代码可以继续保留,用来处理删除失败时的SnackBar提示,无需修改。

这种方案的优势:

  • 避免重复调用API,提升页面响应速度
  • 符合Riverpod的不可变状态管理原则,通过创建新列表而非修改原列表来更新状态
  • 逻辑分工清晰:列表Notifier负责维护列表状态,删除Notifier负责处理API请求及触发本地更新

内容的提问来源于stack exchange,提问作者S. M. JAHANGIR

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 11:57:25