Appearance
Core Concepts: Reactivity
Reactivity is the mechanism by which Fluxus automatically updates parts of your application when the underlying state changes. Fluxus aims for fine-grained reactivity, meaning only the necessary computations and UI updates occur.
How it Works: Dependency Tracking
The foundation of Fluxus reactivity is automatic dependency tracking.
- Tracking Reads: When a provider's recipe function is executed within a
Scope, any calls toread(otherProvider)orwatch(otherProvider)using theScopeReaderare recorded by theScope. This creates a dependency graph where theScopeknows that the current provider depends onotherProvider. - Building the Graph: As providers are read across your application, the
Scopebuilds up a directed graph representing these dependencies. For example, ifproviderCreadsproviderB, andproviderBreadsproviderA, the graph looks likeA -> B -> C.
typescript
import { computedProvider, stateProvider } from '@shtse8/fluxus';
const providerA = stateProvider(10);
const providerB = computedProvider((read) => read(providerA) * 2); // B depends on A
const providerC = computedProvider((read) => read(providerB) + 5); // C depends on BChange Propagation
When the state managed by a provider changes (e.g., a stateProvider is updated), the following happens:
- Notification: The provider whose state changed notifies the
Scope. - Marking Dependents: The
Scopelooks up the dependents of the changed provider in its dependency graph. It marks these direct dependents as "stale". - Recursive Staleness: If a dependent provider is itself a reactive provider (like
computedProvider), the staleness check propagates further up the graph. In our example, ifproviderAchanges,providerBis marked stale. SinceproviderCdepends onproviderB,providerCis also marked stale. - Re-computation (Lazy): A stale provider doesn't immediately recompute its value. Re-computation only happens when:
- The stale provider is explicitly
read()again. - The stale provider has active subscribers (e.g., a component using
useProvideris mounted).
- The stale provider is explicitly
- Notifying Subscribers: If a stale provider recomputes and its value changes, or if a
stateProvideris updated directly, theScopenotifies any active subscribers (like UI components connected viauseProvider).
UI Updates (React Adapter)
The React adapter (fluxus/react-adapter) bridges Fluxus reactivity with React's rendering cycle.
- The
useProvider(myProvider)hook subscribes the component to changes inmyProviderwithin the currentScope. - It uses React's
useSyncExternalStorehook internally. This hook is designed specifically for subscribing to external stores in a way that's safe for concurrent rendering features in React. - When the
Scopenotifies the hook thatmyProvider's state has changed,useSyncExternalStoretriggers a re-render of the component with the new value.
Key Characteristics
- Automatic: You don't manually declare dependencies; they are tracked implicitly via
read/watchcalls. - Fine-grained: Only providers and components affected by a change are updated.
- Lazy: Computations are generally deferred until the value is actually needed.
- Pull-based Computation, Push-based Notification: Values are "pulled" via
read(triggering computation if needed), while updates are "pushed" to active subscribers.
This reactive system allows you to write declarative code focusing on how state is derived, letting Fluxus handle the complexities of keeping everything synchronized efficiently.
Now that you understand the core concepts, let's look specifically at the React Adapter.