读取 class 中继承自 stateNotifier 的状态

Reading a state in a class that inherits from stateNotifier

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

UI

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(){  // ......}
}

提供商 & Class

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;
  }
}

显示以下错误消息。

A value of type 'Todo' can't be assigned to a variable of type 'List'.

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

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

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

class TodoListStateNotifier extends StateNotifier<List<Todo>>{

代码中的状态是不是不能读取?

如果你有更好的方法,请告诉我。

此处的 removeLast() 方法 return 是 Todo 列表中的最后一个 Todo,这就是错误原因

A value of type 'Todo' can't be assigned to a variable of type 'List'

因为您确实在尝试将待办事项分配给列表。

 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 级联运算符和传播运算符。

使用传播运算符 (...) 制作列表的副本,并使用级联运算符为所应用的方法不 return 删除的项目。

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

每次 UI 重建时,都会调用该函数。 错误在这里:

onPressed: context.read(todoNotifierProvider.notifier).deleteTodoList(),

您可以删除 () 或者您可以写:

onPressed: () => context.read(todoNotifierProvider.notifier).deleteTodoList(),