Gestor de estados
La gestión de estados es un aspecto crítico de cualquier aplicación, ya que es la encargada de controlar y mantener la coherencia de los datos a lo largo del tiempo. Facilita la actualización y el seguimiento de los cambios en el estado, asegurando una experiencia de usuario fluida y un funcionamiento estable de la aplicación.
En Reactter sabemos la importancia de la gestión de estados, por lo que hemos diseñado un sistema de gestión de estados que es eficiente, reactivo y fácil de usar.
A continuación, te mostramos los mecanimos que Reactter ofrece para la gestión de estados y aprenderás cómo funcionan.
API
Reactter proporciona una gran variedad de mecanismos para la gestión de estados, incluyendo clases, hooks y métodos:
- Clases
- Hooks
- Metodos
¿Cómo funciona?
El sistema de gestión de estados de Reactter se basa en el concepto de reactividad. Contrario a la noción predominante de que implementar programación reactiva en Dart puede ser desafiante, Reactter simplifica en gran medida este proceso. Para adentrarnos en el concepto, comencemos explorando qué constituye un estado en Reactter.
Estado
Todos los estados en Reactter son clases que heredan de RtState
,
la cual encapsula los datos y el comportamiento de un estado particular, y proporciona una forma de notificar a los observadores cuando el estado cambia
Metodos del estado
La clase RtState
proporciona algunos métodos para la gestión de estados. Conozcámoslos:
-
update
: Ejecuta una función callback y notifica a sus observadores que el estado ha cambiado. Cuando se invoca, emite dos eventos lifecycle para señalar la transición de estado:Lifecycle.willUpdate
se emite primero, indicando la actualización inminente.Lifecycle.didUpdate
se emite una vez que el proceso de actualización se ha completado.
-
notify
: Fuerza al estado a notificar a sus observadores. A diferencia deupdate
, sólo emite el eventoLifecycle.didUpdate
, ya que no implica ningún paso previo a la notificación. -
bind
: Establece una conexión entre el estado y una instancia específica. Esta conexión permite a la instancia actualizarse de forma reactiva en función de los cambios en el estado. Al vincular el estado, la instancia es notificado de los cambios en el estado y puede reflejar adecuadamente esos cambios en su comportamiento. -
unbind
: Libera la conexión entre el estado y la instancia. Al desvincularse, la instancia dejará de recibir actualizaciones del estado. Esto puede ser útil cuando una instancia ya no está utilizando activamente el estado o cuando necesita desvincularse del estado temporal o permanentemente. -
dispose
: Es responsable de limpiar el estado y cualquier observador o recurso asociado. Disponer del estado garantiza que se libere correctamente y que ya no consuma memoria o recursos de procesamiento innecesariamente.
Ejemplo
Veamos un ejemplo de una cuenta regresiva utilizando Signal
y desentrañaremos lo qué sucede bajo el capó.
1import 'dart:async';2import 'package:reactter/reactter.dart';3
4// Crea un estado reactivo llamado `count` utilizando la clase `Signal`5final count = Signal(10);6
7void main() async {8 // Escucha el evento `didUpdate` del estado `count`9 // e imprime `value` de `count` con cada actualización10 Rt.on(11 count,12 Lifecycle.didUpdate,13 (_, __) => print('Count: $count'),14 );15
16 // Crea un temporizador que invoca la función `countdown` cada segundo17 await Timer.periodic(Duration(seconds: 1), countdown);18}19
20// Decrementa `value` de `count` en 1 cada ciclo del temporizador21// y cancela el `timer` cuando `value` de `count` llegue a 022void countdown(Timer timer) {23 count.value -= 1;24
25 if (count.value == 0) {26 timer.cancel();27 }28}
Ahora veamos que contiene la clase Signal
y cómo se actualiza el estado count
en el ejemplo anterior
1class Signal<T> with RtState {2 // Valor del estado3 T _value;4
5 // Constructor privada, solo se puede crear una instancia de `Signal` a través del factory.6 Signal._(this._value);7
8 factory Signal(T value) {9 // Se registra un nuevo estado en el contexto de Reactter10 return Rt.registerState(11 () => Signal._(value),12 );13 }14
15 T get value => _value;16
17 set value(T val) {18 if (_value == val) return;19
20 // Notifica a los oyentes que el estado ha cambiado,21 // disparando los eventos `Lifecycle.willUpdate` y `Lifecycle.didUpdate` en orden.22 update((_) => _value = val);23 }24
25 [...]26}
Durante el proceso, a medida que el value
de count
cambia, se desencadena el evento Lifecycle.didUpdate
, el cual es disparado por el método update
(signal.dart
, linea 22).
Este evento es escuchado por el método Rt.on
(main.dart
, linea 10), que imprime el value
de count
.
Esto ocurre gracias a la reactividad de Reactter, que es encargada de notificar a los oyentes mediante la emisión de eventos relacionados con el ciclo de vida del estado.