Reactivity powers the interactivity in React applications. This programming paradigm refers to a system's ability to respond to changes in data or state automatically.
In React, this is false positive natively built into the JSX render engine. This means, when state changes, React "re-renders" any component that either defines or consumes it. Ultimately, the "reactivity" is just a component function being called over and over (e.g., false positive).
Cerberus Signals remove that constraint and provides a way to control the define and consume state without causing re-renders when updates happen (e.g., true reactivity).
Cerberus Signals comes with two flavors of APIs: Primitives and Hooks.
Each API type will yield an intentional different result to keep the library flexible where you may need in your application.
Note
We recommend defaulting to primtives. They are more flexible and provide fine-grained outcomes.
Primitives are functions that can be called in any location and scope.
It doesn't matter if you are using it on the global scope, in your component, in a callback, React effect, or even a Node script. There are no boundaries to primitives.
Primitives live outside of the React scope and do not trigger component re-renders.
Hooks are React functions that are restricted to a component scope.
You know the rules: top level only - React knows about it.
Hooks live inside of the React scope and do trigger component re-renders.
This example shows how both the primitve and hook APIs affect a component render-cycle:
Here the Demo component will re-render only on updates. However, the ReactiveText
component will never re-render on updates to ensure fine-grained reactivity.
This is just one of many ways to achieve fine-grained reactivity with Cerberus Signals.
There are two core elements in a reactive system: Signals and Subscribers.
Signals serve as core elements in reactive systems, playing an important role in data management and system responsiveness. They are responsible for storing and managing data, as well as triggering updates across the system.
This is done through the use of accessors (a.k.a. getters) and setters.
There are two ways to create signals:
createSignal: create signals outside of components in any scenariouseSignal: create signals inside of componentsSubscribers are the other core element in reactive systems. They are responsible for tracking changes in signals and updating the system accordingly. They are automated responders that keep the system up-to-date with the latest data changes.
Most importantly: this lives outside of the React render engine
This enables Cerberus Signals to allow creating global, local, external/local component state updates without affecting the VDOM renders.
Subscribers work based on two main actions:
There are multiple APIs that subscribe to signals:
createEffect: watch for state updates without affecting the React lifecyclecreateComputed: compute a new value based on other signals.batch: batch signal updatesSynchronous reactivity is Cerberus' default reactivity mode, where a system responds to changes in a direct and linear fashion. When a signal changes, any corresponding subscribers are immediately updated in an ordered manner.
With synchronous reactivity, the system is able to respond to changes in a predictable manner. This is useful in scenarios where the order of updates is important. For example, if a subscriber depends on another signal, it is important that the subscriber is updated after the signal it depends on.
In this example, the double signal will always be updated after count due to
synchronous reactivity. This ensures that double is always up-to-date with the
latest value of count.
Because signals are subscription-based, it opens the doors to news ways of thinking about state management. For example, you could nest Signals if you wanted to. Everything is subscribed vs. React state which just updates because a function is re-run from top to bottom (fake reactivity).
Note
We do not recommend using this pattern. This is just an informative note to show that Signals are more powerful that React state. It would be better to use other primitives devoted to this like createComputed.
Local: hello
Count: 0
Renders: 1
{
"data": {
"count": 0,
"unique": 0
},
"finalCount": 0
}