Aller au contenu principal

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 son ChangeNotifierProvider.
  • le support de l'état muable, même si l'état immuable est préférable
info

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),
),
],
);
}
}