Reactive Engine
Deep dive into Signals, Effects, and Fluxy's reactivity.
Reactive Engine
Zero-Boilerplate State. Atomic Rebuilds.
Fluxy's Heart is the Reactive Engine. Unlike Provider or Bloc which often trigger unnecessary full-screen rebuilds, Fluxy uses Signals to target specific properties of a single widget, resulting in unmatched performance.
The Signal (flux<T>)
A Signal is a reactive wrapper around any value. When the value changes, only the widgets observing that specific signal are updated.
Comparison
Standard Flutter (State Management)
class MyState extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners(); // Rebuilds entire widget tree!
}
}Fluxy Reactive Engine
final count = flux(0); // Defined once
// Rebuilds ONLY this text
Fx(() => Fx.text("Count: ${count.value}"))
// Update value anywhere
count.value++;Form Signals (fluxField)
Specialized signals for inputs that handle validation and "touched" states automatically.
Comparison
Standard Flutter
String? error;
String val = "";
void validate(String s) {
if (s.isEmpty) error = "Required";
setState(() {});
}Fluxy DSL
final name = fluxField("")
.required("Min name")
.minLength(3);
// Error and state are managed internallyComputed Signals (computedFlux)
Derived state that automatically updates when its dependencies change.
final price = flux(100);
final tax = flux(0.18);
// Automatically updates when price or tax changes
final total = flux(() => price.value * (1 + tax.value));Async Signals (AsyncSignal)
Manage asynchronous tasks (API calls, Database queries) with built-in loading and error states.
final userSignal = AsyncSignal<User>(
config: AsyncConfig(
retries: 3,
debounce: 500.ms,
timeout: 10.sec,
),
);
// Trigger fetch
userSignal.fetch(() => api.getUser(id));
// Reactive UI binding
Fx(() => userSignal.on(
loading: () => Fx.loader.shimmer(),
error: (err) => Fx.text("Error: $err"),
data: (user) => Fx.text("Welcome, ${user.name}"),
));Advanced Conditionals (Fx.cond)
Refined alternatives to ternary operators for complex UI branching.
Single Condition
Fx.cond(isLoggedIn, ProfilePage(), LoginPage())Multiple Cases
Fx.cond.multiple({
isLoading: Fx.loader.show(),
hasError: Fx.text("Error occurred"),
isGuest: Fx.button("Login"),
}, fallback: WelcomeDashboard())Switcher
Fx.cond.switcher(currentView, {
View.home: HomeView(),
View.settings: SettingsView(),
})Common "Gotchas" & Solutions
| Issue | Standard Flutter Pain | Fluxy Solution |
|---|---|---|
| Rebuild Over-triggering | Consumer/Selector complexity. | Atomic Rebuilds: Only the specific Fx builder closure rebuilds. |
| State Disposal | Manual controller.dispose(). | Auto-GC: Signals are garbage collected when no longer observed. |
| Initialization Race | initState async gaps. | AsyncSignal: Built-in .on(loading: ..., data: ...) pattern. |