Binding State to Dependency
A Reactter state( RtState
) such as Signal
or any Hooks
can be bound to the dependency, allowing the state to be manipulated directly from the dependency and to notify its listeners about any changes.
Additionally, it ensures that the state is automatically disposed of when the dependency is no longer needed.
By integrating state directly within dependencies, you benefit from cleaner and more maintainable code. The automatic handling by Reactter means less boilerplate and fewer errors related to manual state management, leading to a more efficient development process. This approach simplifies the synchronization between state and its associated dependency, enhancing the overall responsiveness and reliability of your application.
Automatic binding
For that happened automatically, the state must be declared as a property or within constructor of the dependency. When this is done, Reactter automatically takes care of binding the state to the dependency, ensuring seamless state management and reactivity, e.g.:
1import "package:reactter/reactter.dart";2
3class CountController {4 // State declared as property5 final uCount = UseState(0);6
7 CountController() {8 // State declared within constructor9 UseEffect(() {10 print("Count: ${uCount.value}");11 }, [uCount]);12 }13}
In the example above, the uCount
state is declared as a property of the CountController
class and the UseEffect
hook is used within the constructor to react to changes in the uCount
state, printing its value whenever it changes.
This automatically binds the uCount
state and UseEffect
hook to the CountController
instance, demonstrates how Reactter handles the binding and reactivity seamlessly.
Lazy binding
When a state is declared lazily, it is not automatically bound to the dependency.
In such cases, you can use the Rt.lazyState
method to bind the state to the dependency, e.g.:
1import "package:reactter/reactter.dart";2
3class CountController {4 final int initialCount;5
6 late final uCount = Rt.lazyState(7 () => UseState(this.initialCount),8 this,9 );10
11 CountController([this.initialCount = 0]) {12 UseEffect(() {13 print("Count: ${uCount.value}");14 }, [uCount]);15 }16}
In the example above, the uCount
state is declared lazily using the late
keyword.
To bind the state to the CountController
instance, the Rt.lazyState
method is used, passing the state creation function and the dependency instance as arguments.
This ensures that when uCount
is accessed, it will be automatically bound to the CountController
instance.
Manual binding
While automatic binding simplifies state management, there may be scenarios where you need to manually bind the state to a dependency. Manual binding provides greater control over how and when the state is associated with the dependency.
To manually bind a state to a dependency, you need to explicitly link the state within the dependency using the bind
method of the state, e.g.:
1class CountController {2 late final uCount = UseState(this.initialCount);3
4 final int initialCount;5
6 CountController([this.initialCount = 0]) {7 count.bind(this);8 }9}
In the example above, the uCount
state is declared lazily using the late
keyword.
To manually bind the state to the CountController
instance, the bind
method is called within the constructor, passing the dependency instance as an argument.
This ensures that the uCount
state is associated with the CountController
instance, e.g.:
Automatic unbinding
When a dependency is deleted, the associated state is automatically disposed of. This automatic unbinding mechanism simplifies state management and reduces the risk of memory leaks or resource wastage.
In the example below, the uCount
state is automatically disposed of when the CountController
instance is deleted, ensuring that resources are released efficiently:
1import "./count_controller.dart";2
3void main() {4 final controller = Rt.create(() => CountController(10));5 controller.uCount.value += 2; // Count: 126 Rt.delete<CountController>();7 controller.uCount.value += 3; // Error: "Can't update when it's been disposed"8}
Manual unbinding
In some cases, you may need to manually unbind a state from a dependency. Manual unbinding provides greater control over when the state is released and can be useful in scenarios where you want to detach the state temporarily or permanently.
To manually unbind a state from a dependency, you can use the unbind
method of the state, e.g.:
1class CountController {2 late final uCount = UseState(this.initialCount);3
4 final int initialCount;5
6 CountController([this.initialCount = 0]) {7 count.bind(this);8 }9
10 void dispose() {11 count.unbind(this);12 }13}