Una solución de gestión del estado reactiva fácil de entender para Flutter.
El estado se mantiene en uno o múltiples instancias de Value o clases similares que implementan ValueNotifier . Estas son interfaces de aleteo estándar que todos conocen por TextEditingController , Animation , etc.
Además, puede usar ListValue y MapValue para crear valores observables List y Map que pueden notificarle sobre los eventos de cambio de grano fino (en lugar de que el valor completo cambie).
AutoBuild reconstruye automáticamente sus widgets cuando un ValueNotifier (o cualquier Listenable ) desencadena una notificación. Es similar al ValueListenableBuilder de Flutter, pero puede rastrear múltiples dependencias y también funciona con Listenable .
No es necesario llamar addListener / removeListener . Simplemente get() el valor directamente mientras AutoBuild se encarga de rastrear sus dependencias.
A diferencia de InheritedWidget y Provider , obtienes un control de grano fino sobre lo que se reconstruye.
Las clases estándar de Flutter como TextEditingController y Animation implementan ValueListenable y, por lo tanto, funcionan bien con AutoBuild .
DerivedValue es un valor observable que se calcula (se deriva) de otros valores observables.
Además, ListValue y MapValue proporcionan .map() y otras operaciones para crear contenedores derivados que se mantengan actualizados por elemento por elemento.
El código resultante es mucho más simple que la misma solución en Bloc o Redux.
StreamBuilder , sin carga asincrónica de widgets (a menos que realmente lo necesite).switch() . Nota: Consulte también la referencia para obtener más detalles.
Un simple ejemplo AutoBuild :
import 'package:flutter/material.dart' ;
import 'package:reactive_state/reactive_state.dart' ;
class MyPage extends StatelessWidget {
MyPage ({ Key key, @required this .counter}) : super (key : key);
final ValueNotifier < int > counter;
@override
Widget build ( BuildContext context) {
return Scaffold (
appBar : AppBar (title : Text ( 'Counter' )),
body : Column (
children : < Widget > [
AutoBuild (builder : (context, get , track) {
return Text ( 'Counter: ${ get ( counter )}' );
}),
MaterialButton (
onPressed : () => counter.value ++ ,
child : Text ( 'Increment' ),
),
],
),
);
}
}Tenga en cuenta que en las aplicaciones del mundo real no debe mutar directamente el estado, sino ponerlo en métodos separados, por ejemplo, en un objeto hecho accesible a través del paquete del proveedor.
Además, eche un vistazo al ejemplo en el repositorio.
Fuera de los widgets, es posible que aún desee reaccionar a los cambios de estado. Puede hacerlo con autoRun() y AutoRunner (consulte la referencia para más detalles).
Como alternativa al ValueNotifier también puede usar la clase Value reactive_state que proporciona un método update() para modificar objetos más complejos:
class User {
String name = '' ;
String email = '' ;
// ...
}
var userValue = Value ( User ());
userValue. update ((user) {
user.name = 'Adam' ;
user.email = '[email protected]' ;
}); Esto es similar a llamar setState() con StatefulWidget . Con update() puede cambiar múltiples atributos y Value activará una sola notificación una vez terminada, incluso si no se cambió nada (por lo que no necesita implementar operadores de comparación para objetos complejos).
DerivedValue es un ValueListenable calculado dinámicamente que actualiza su valor cada vez que cambian sus dependencias:
var user = Value ( User ());
var emailLink = DerivedValue (( get , track) => 'mailto:${ get ( user ). email }' ); Aquí, emailLink se puede observar por sí solo y se actualiza cada vez que user se modifique.
Un ejemplo simple que muestra algunas cosas que se pueden hacer:
final listValue = ListValue ( < int > []);
final mappedList = listValue. map ((x) => x. toString ());
final listToMap = mappedList. toMap ((x) => MapEntry ( 2 * int . parse (x), x));
final invertedMap = listToMap. map ((k, v) => MapEntry (v, k));
listValue. addAll ([ 4 , 1 ]);
// => invertedMap.value == {'4': 8, '1': 2}