fx_rx 0.0.1
fx_rx: ^0.0.1 copied to clipboard
Tiny reactive state management for Flutter with zero boilerplate.
fx_rx #
A tiny reactive state management library for Flutter.
Features #
Rx<T>: reactive value for any typeRxView(() => Widget): rebuilds automatically whenRxvalues used inside changeRxList,RxMap,RxSet: reactive collectionscomputed(() => ...): derived reactive values that update automaticallyselect(() => ...): distinct derived values (notifies only when selected value changes)RxAsync<T>: simple async state (loading / data / error)- Effects:
ever(rx, ...),once(rx, ...),debounce(rx, ...),interval(rx, ...) batch(() { ... }): group multiple writes into a single notify wave
Install #
Add to your pubspec.yaml:
dependencies:
fx_rx: ^0.0.1
Quick start #
import 'package:fx_rx/fx_rx.dart';
final count = Rx(0);
RxView(() => Text("Count: ${count.value}"));
void increment() => count.value++;
Extensions #
final name = "John".rx; // Rx<String>
final age = 30.rx; // Rx<int>
Derived state (computed) #
final first = "John".rx;
final last = "Cena".rx;
final fullName = computed(() => "${first.value} ${last.value}");
RxView(() => Text(fullName.value));
Async state (RxAsync) #
final users = RxAsync<List<String>>();
Future<void> load() async {
await users.run(() async {
await Future.delayed(const Duration(seconds: 1));
return ["A", "B", "C"];
});
}
RxView(() => users.when(
idle: () => const Text("Idle"),
loading: () => const CircularProgressIndicator(),
data: (d) => Text("Users: ${d.length}"),
error: (e) => Text("Error: $e"),
));
Reactive collections #
final items = RxList<String>();
items.add("A");
RxView(() => Text("Total: ${items.length}"));
Effects #
final disposer = ever(count, (v) {
// do something when count changes
});
disposer.dispose(); // stop listening
Batch #
batch(() {
a.value = 1;
b.value = 2;
});
License #
MIT. See LICENSE.
Select (distinct derived) #
final user = Rx({"name": "A", "age": 1});
// Only rebuild when "age" changes:
final age = select(() => user.value["age"]);
RxView(() => Text("Age: ${age.value}"));
More effects #
once #
final d = once(count, (v) {
// runs once on first change
});
d.dispose();
debounce #
final d = debounce(query, const Duration(milliseconds: 300), (v) => search(v));
d.dispose();
interval #
final d = interval(scroll, const Duration(milliseconds: 200), (v) => log(v));
d.dispose();
Example app #
A runnable Flutter example is included in example/.
cd example
flutter run