首页 > 解决方案 > 读取继承自 stateNotifier 的类中的状态

问题描述

我正在尝试使用 flutter_riverpod 的 stateNotifierProvider 检索和删除 TodoList。在下面的代码中,fetchTodoList 方法工作正常,但 deleteTodoList 方法不起作用。

用户界面

class TodoList extends ConsumerWidget {
  @override
  Widget build(BuildContext context, ScopedReader watch) {
    final todoAsyncValue = watch(todoFutureProvider);
    return Padding(
      padding: const EdgeInsets.all(8),
      child: todoAsyncValue.when(
        data: (todoList) => SingleChildScrollView(
          child: Scaffold(
            body: Column(
              children: _buildTodoList(todoList),
            ),
            floatingActionButton: FloatingActionButton(
              onPressed: context.read(todoNotifierProvider.notifier).deleteTodoList(),
              child: const Icon(Icons.delete),
            ),
          ),
        ),
        loading: () => const Center(child: const CircularProgressIndicator()),
        error: (error, stack) => Text(error.toString()),
      ),
    );
  }
  _buildTodoList(){  // ......}
}

提供者和类别

final todoNotifierProvider = StateNotifierProvider<TodoListStateNotifier, List<Todo>>((ref) {
    return TodoListStateNotifier();
});

final todoFutureProvider = FutureProvider<List<Todo>>((ref) async {
    final todo= ref.read(todoNotifierProvider.notifier);
    await todo.fetchTodoList();
    return ref.watch(todoNotifierProvider);
});


class TodoListStateNotifier extends StateNotifier<List<Todo>>{
  TodoListStateNotifier(): super([]);

  Future<void> fetchTodoList() async {
    final todoClient = TodoClient();
    state = await todoClient.fetchTodoList(); 
  }

  void deleteTodoList() {
    var list = <Todo>[];
    list = state.removeLast();
    state = list;
  }
}

显示以下错误消息。

“Todo”类型的值不能分配给“List”类型的变量。

另外,如果我将代码转换为以下代码,则不会显示错误,但不会正确反映在 UI 中。

void deleteTodoList() {
    state.removeLast();
  }

我假设下面代码中定义的类型是状态的类型,我错了吗?

class TodoListStateNotifier extends StateNotifier<List<Todo>>{

是不是无法读取代码中的状态?

如果您知道更好的方法,请告诉我。

标签: flutterdartriverpod

解决方案


在这里,该removeLast()方法返回列表中的Todo最后一个Todo,这就是错误的原因

“Todo”类型的值不能分配给“List”类型的变量

因为您确实在尝试将 Todo 分配给列表。

 void deleteTodoList() {
    var list = <Todo>[];
    list = state.removeLast();
    state = list;
  }

现在使用第二个示例,在这里您有效地删除了最后一项,但不会发出新状态,因此 UI 不会重建。

void deleteTodoList() {
    state.removeLast();
  }

备择方案:

  1. 过滤并删除您想要的特定待办事项
    state = state.where((todo) => todo.id != target.id).toList()
  1. 不要将删除的值分配给变量
  void deleteTodoList() {
    var list = <Todo>[];
state.removeLast();
    list=state;
    state = list;
  }
  1. 使用 dart 级联运算符和扩展运算符。

使用扩展运算符(...)制作列表的副本,并使用应用方法的级联运算符不返回已删除的项目。

  void deleteTodoList() {
    state=[...state..removeLast()];
  }  

推荐阅读