(Flutter/Riverpod)在任何情况下都不应该使用Riverpod中提供者主体内的ProviderRefere



我有一个关于如何在Riverpod中使用ProviderReference.read的问题。

我在下面的正式网站上发现了一条不要打电话给提供者参考的警告。阅读提供者的身体内部。

我可以不听就阅读提供者吗?https://riverpod.dev/docs/concepts/combining_providers/#can-i-read-a-provider,无需登录即可使用

不要在提供者体内调用READ

final myProvider = Provider((ref) {
// Bad practice to call `read` here
final value = ref.read(anotherProvider);
});

但是,另一方面,我在下一页中发现了另一个关于ProviderReference.read的例子,其中ref.read在提供者的主体内部使用。

https://pub.dev/documentation/riverpod/latest/all/Provider-class.html

创建一个依赖于许多提供者的对象。
final cityProvider = Provider((ref) => 'London');
final countryProvider = Provider((ref) => 'England');
final weatherProvider = Provider((ref) {
final city = ref.read(cityProvider);   // <------------------- `ref.read` is used 
final country = ref.read(countryProvider);  // <-------------- `ref.read` is used 
return Location(city: city, country: country);
});
class Location {
Location({this.city, this.country});
final String city;
final String country;
String get label => '$city ($country)';
}

因此,我想提出一个问题:我仍然不应该在提供者的主体内调用ProviderReference.read?

如果是,让我再问一个问题:我应该如何处理以下代码,在这些代码中,我在提供者的主体中使用ProviderReference.read。我希望有人给我一个好主意。

final todoListProvider = StateNotifierProvider<TodoListController>((ref) {
final todosRepository = ref.read(repositoryProvider); // <---------- using `ref.read` here.
return TodoListController(
todosRepository: todosRepository,
);
});
class TodoListController extends StateNotifier<TodoListState> {
TodoListController({
List<Todo> todos = const [],
@required this.todosRepository,
})  : assert(todosRepository != null),
super(TodoListState(todos, loading: false)) {
_loadTodos();
}
final TodosRepository todosRepository;
Future<void> _loadTodos() async {
state = (state.copyWith(loading: true));
final todos = await todosRepository.loadTodos();
state = (state.copyWith(
todos: todos.map(Todo.fromEntity).toList(),
loading: false,
));
}
}
@freezed
abstract class TodoListState with _$TodoListState {
const factory TodoListState({
List<Todo> todos, {
@required bool loading,
}) = _TodoListState;
}

我认为重点是这没有错,这是一种糟糕的做法。正确的方法是将ProviderReference作为参数传递给StateNotifier

Provider((ref) => TodoListController(ref,
todosRepository: todosRepository,
);)

然后在StateNotifier:

// constructor
TodoListController(this._ref, [...]);
// the reference as a class member
final ProviderReference _ref;

最新更新