# Riverpod: Gestión de Estado Moderna
**Riverpod** es una reescritura completa de `Provider` creada por el mismo autor (Remi Rousselet). Soluciona los problemas fundamentales de Provider (dependencia del árbol de widgets, errores en runtime) y ofrece un sistema de inyección de dependencias y gestión de estado reactivo, seguro y testearle.
## ¿Por qué Riverpod?
- **Compile-safe:** No más `ProviderNotFoundException`. Si compila, funciona.
- **Independiente de Flutter:** Puedes usarlo en Dart puro (backend, CLI).
- **No depende del BuildContext:** Puedes leer providers desde cualquier lugar.
- **Caching y Auto-dispose:** Manejo inteligente de recursos.
## Conceptos Clave
### Providers Globales
En Riverpod, los providers se declaran como variables globales. No te asustes, son inmutables y seguros.
```dart
// Un provider simple de solo lectura
final nameProvider = Provider((ref) => 'Riverpod');
// Un provider de estado mutable
final counterProvider = StateProvider((ref) => 0);
```
### ProviderScope
Debes envolver tu app en `ProviderScope` para que Riverpod funcione.
```dart
void main() {
runApp(
ProviderScope(
child: MyApp(),
),
);
}
```
## Leyendo Providers (ConsumerWidget)
En lugar de `StatelessWidget`, usamos `ConsumerWidget`, que nos da acceso a un objeto `WidgetRef`.
```dart
class CounterPage extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
// 1. Watch: Reconstruye el widget cuando cambia el valor
final count = ref.watch(counterProvider);
return Scaffold(
body: Center(child: Text('$count')),
floatingActionButton: FloatingActionButton(
onPressed: () {
// 2. Read: Lee el valor una vez (o su controlador) sin escuchar
// Modificamos el estado
ref.read(counterProvider.notifier).state++;
},
child: Icon(Icons.add),
),
);
}
}
```
## StateNotifierProvider (Lógica Compleja)
Para lógica más compleja, usamos `StateNotifier` (similar a Cubit).
```dart
// Estado inmutable
class Todo {
final String id;
final String description;
final bool completed;
// constructor...
}
// Lógica de negocio
class TodoList extends StateNotifier
- > {
TodoList() : super([]);
void add(String description) {
state = [
...state,
Todo(id: uuid.v4(), description: description, completed: false),
];
}
void toggle(String id) {
state = [
for (final todo in state)
if (todo.id == id)
todo.copyWith(completed: !todo.completed)
else
todo
];
}
}
// Provider
final todoListProvider = StateNotifierProvider
Este apartado profundiza en los conceptos clave, proporcionando ejemplos prácticos y mejores prácticas para su aplicación en proyectos reales.
Al comprender estos detalles, podrás diseñar soluciones más robustas, mantenibles y escalables en tus aplicaciones Flutter y Dart.