Uma solução de gerenciamento de estado reativo fácil de entender para o Flutter.
O estado é mantido em uma ou várias instâncias de Value ou classes semelhantes que implementam ValueNotifier . Essas são interfaces de vibração padrão que todo mundo sabe do TextEditingController , Animation etc.
Além disso, você pode usar ListValue e MapValue para criar valores observáveis List e Map que podem notificá-lo sobre eventos de mudança de granulação fina (em vez de toda a mudança de valor).
AutoBuild reconstrói automaticamente seus widgets quando um ValueNotifier (ou qualquer qualquer Listenable ) aciona uma notificação. É semelhante ao ValueListenableBuilder do Flutter, mas pode rastrear várias dependências e também funciona com Listenable .
Não há necessidade de ligar para addListener / removeListener . Basta get() o valor diretamente enquanto AutoBuild cuida do rastreamento de suas dependências.
Ao contrário InheritedWidget e Provider , você obtém controle de refrigerante sobre o que é reconstruído.
As classes de vibração padrão como TextEditingController e Animation implementam ValueListenable e, portanto, funcionam bem com AutoBuild .
DerivedValue é um valor observável que é calculado (derivado) de outros valores observáveis.
Além disso, ListValue e MapValue fornecem .map() e outras operações para criar recipientes derivados que se mantêm atualizados por elemento.
O código resultante é muito mais simples que a mesma solução no bloco ou redux.
StreamBuilder , sem carga assíncrona de widgets (a menos que você realmente precise).switch() . Nota: Consulte também a referência para obter detalhes.
Um exemplo simples 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' ),
),
],
),
);
}
}Observe que, em aplicativos do mundo real, você não deve mutações diretamente, mas colocá-lo em métodos separados, por exemplo, um objeto tornado acessível através do pacote de provedor.
Além disso, dê uma olhada no exemplo no repositório.
Fora dos widgets, você ainda pode reagir às mudanças de estado. Você pode fazer isso com autoRun() e AutoRunner (consulte a referência para obter detalhes).
Como alternativa ao ValueNotifier você também pode usar a classe Value do reactive_state , que fornece um método update() para modificar objetos mais complexos:
class User {
String name = '' ;
String email = '' ;
// ...
}
var userValue = Value ( User ());
userValue. update ((user) {
user.name = 'Adam' ;
user.email = '[email protected]' ;
}); Isso é semelhante ao Calling setState() com StatefulWidget . Com update() você pode alterar vários atributos e Value desencadeará uma única notificação uma vez concluído - mesmo que nada fosse alterado (para que você não precise implementar operadores de comparação para objetos complexos).
DerivedValue é um ValueListenable calculado dinamicamente que atualiza seu valor sempre que suas dependências mudam:
var user = Value ( User ());
var emailLink = DerivedValue (( get , track) => 'mailto:${ get ( user ). email }' ); Aqui, emailLink pode ser observado por conta própria e é atualizada sempre que user é modificado.
Um exemplo simples mostrando algumas coisas que podem ser feitas:
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}