ChangeNotifierProvider
ChangeNotifierProvider
(flutter_riverpod/hooks_riverpod uniquement) est un provider qui
est utilisé pour écouter et exposer un ChangeNotifier depuis Flutter lui-même.
L'utilisation de ChangeNotifierProvider
est déconseillée par Riverpod et existe principalement pour :
- faire une transition facile à partir de
package:provider
lors de l'utilisation de sonChangeNotifierProvider
. - le support de l'état muable, même si l'état immuable est préférable
Préférez utiliser StateNotifierProvider à la place.
Envisagez d'utiliser ChangeNotifierProvider
uniquement si
vous êtes absolument certain que vous voulez un état muable.
L'utilisation d'un état muable au lieu d'un état immuable peut parfois être plus efficace.
L'inconvénient est qu'il peut être plus difficile à maintenir et peut casser diverses fonctionnalités.
Par exemple, l'utilisation de provider.select
pour optimiser les reconstructions de
vos widgets peut ne pas fonctionner si votre état est mutable, car select
pensera que la valeur n'a pas changé.
Ainsi, l'utilisation de structures de données immuables peut parfois être plus rapide.
Il est donc important de faire des tests spécifiques à votre cas d'utilisation,
afin de vous assurer que vous gagnez réellement en performance en utilisant ChangeNotifierProvider
.
A titre d'exemple d'utilisation, on peut utiliser ChangeNotifierProvider
pour implémenter une todo-list.
Cela nous permettrait d'exposer des méthodes telles que addTodo
pour permettre à
l'interface utilisateur de modifier la liste des tâches à accomplir en fonction des
interactions de l'utilisateur :
class Todo {
Todo({
required this.id,
required this.description,
required this.completed,
});
String id;
String description;
bool completed;
}
class TodosNotifier extends ChangeNotifier {
final todos = <Todo>[];
// Permettons à l'interface utilisateur d'ajouter des todos.
void addTodo(Todo todo) {
todos.add(todo);
notifyListeners();
}
// Permettons la suppression des todos
void removeTodo(String todoId) {
todos.remove(todos.firstWhere((element) => element.id == todoId));
notifyListeners();
}
// Marquons une tâche comme étant terminée
void toggle(String todoId) {
for (final todo in todos) {
if (todo.id == todoId) {
todo.completed = !todo.completed;
notifyListeners();
}
}
}
}
// Enfin, nous utilisons StateNotifierProvider pour permettre à l'IU d'interagir
// avec notre TodosNotifier class.
final todosProvider = ChangeNotifierProvider<TodosNotifier>((ref) {
return TodosNotifier();
});
Maintenant qu'on a défini un ChangeNotifierProvider
, nous pouvons l'utiliser pour interagir
avec la liste des tâches dans notre interface utilisateur :
class TodoListView extends ConsumerWidget {
const TodoListView({super.key});
Widget build(BuildContext context, WidgetRef ref) {
// reconstruire le widget lorsque la liste des tâches change.
List<Todo> todos = ref.watch(todosProvider).todos;
// On re-affiche (render) les todos dans une ListView
return ListView(
children: [
for (final todo in todos)
CheckboxListTile(
value: todo.completed,
// En appuyant sur la tâche, le statut de celle-ci est modifié.
onChanged: (value) =>
ref.read(todosProvider.notifier).toggle(todo.id),
title: Text(todo.description),
),
],
);
}
}