UseAsyncState
UseAsyncState
is a hook that allows to declare state variables and manipulate its value
asynchronously, which in turn notifies about its changes to listeners.
Syntax
UseAsyncState<T>( T initialValue, Future<T> asyncFunction(),);
// UseAsyncState with argumentsUseAsyncState<T, A>.withArg( T initialValue, Future<T> asyncFunction(A arg),);
UseAsyncState
accepts these arguments:
initialValue
: Initial value ofT
type that it will hold.-
asyncFunction
: A function that returns aFuture<T>
to update the state asynchronously. This function is called by theresolve
method and sets thevalue
property.
Properties & Methods
UseAsyncState
provides the following properties and methods:
value
: A getter that allows to read its state.status
: A getter that allows to read its status. It can be:UseAsyncStateStatus.standby
: Represents the standby status, indicating that the state is idle.UseAsyncStateStatus.loading
: Denotes the loading status, indicating that an asynchronous operation is in progress.UseAsyncStateStatus.done
: Indicates that the asynchronous operation has been successfully completed.UseAsyncStateStatus.error
: Signifies that an error has occurred during the asynchronous operation.
error
: A getter that allows to get the error object when theasyncFunction
fails.-
resolve
: A method that updates the state asynchronously by calling theasyncFunction
function.- Syntax:
FutureOr<T?> resolve();// for UseAsyncState.withArgFutureOr<T?> resolve(A arg);
- Syntax:
-
when
: A method that allows to computed a value depending on its status.- Syntax:
R? when<R>({WhenValueReturn<T, R>? standby,WhenValueReturn<T, R>? loading,WhenValueReturn<T, R>? done,WhenErrorReturn<R>? error,});
- Arguments:
-
standby
: A function that returns a value when the state isUseAsyncStateStatus.standby
. -
loading
: A function that returns a value when the state isUseAsyncStateStatus.loading
. -
done
: A function that returns a value when the state isUseAsyncStateStatus.done
. -
error
: A function that returns a value when the state isUseAsyncStateStatus.error
.
-
- Syntax:
-
Methods inherited from
RtState
(Learn more here):-
update
: A method to notify changes after run a set of instructions. -
refresh
: A method to force to notify changes. - *
bind
: A method to bind an instance to it. - *
unbind
: A method to unbind an instance to it. - *
dispose
: A method to remove all listeners and free resources.
-
Usage
Declaration
UseAsyncState
can be initialized using the constructor class:
final uAsyncState = UseAsyncState<String>('Initial value', asyncFunction);
Future<String> asyncFunction() async { await Future.delayed(Duration(seconds: 2)); return "Resolved value";}
Resolving & reading the state
UseAsyncState
has a resolve
method that updates the state asynchronously by calling the asyncFunction
function.
After resolving the state, you can read the value
, like this:
print("${uAsyncState.value}"); // Initial valueawait uAsyncState.resolve();print("${uAsyncState.value}"); // Resolved value
Using with argument
UseAsyncState
can be used with arguments using the withArg
constructor:
final uAsyncStateWithArg = UseAsyncState.withArg<String, int>( 'Initial value', asyncFunctionWithArg);
Future<String> asyncFunctionWithArg(int arg) async { await Future.delayed(Duration(seconds: 2)); return "Resolved value with arg: $arg";}
To resolve the state with an argument, you can use the resolve
method with the argument.
After resolving the state, you can read the value
, like this:
print("${uAsyncStateWithArg.value}"); // Initial valueawait uAsyncStateWithArg.resolve(10);print("${uAsyncStateWithArg.value}"); // Resolved value with arg: 10
If you want to add more arguments, you can supply it using the Record
(if your proyect support)
or Args
(A generic arguments provided by Reactter), e.g.:
final uAsyncStateWithArgs = UseAsyncState.withArg<String, ArgsX3<String>>( 'Initial value', asyncFunctionWithArgs);
Future<String> asyncFunctionWithArgs(ArgsX3<String> args) async { await Future.delayed(Duration(seconds: 2)); return "Resolved value with args: ${args.arg}, ${args.arg2}, ${args.arg3}";}
print("${uAsyncStateWithArgs.value}"); // Initial valueawait uAsyncStateWithArgs.resolve(ArgsX3('arg1', 'arg2', 'arg3'));print("${uAsyncStateWithArgs.value}"); // Resolved value with args: arg1, arg2, arg3
Using with Memo
UseAsyncState
does not cache the resolving value
, meaning that it will resolve the value
every time resolve
is called, potentially impacting performance, especially if the asyncFunction
is expensive. In this case, you should consider using Memo
to cache the resolving value
, e.g.:
1final translateState = UseAsyncState.withArg<String?, ArgsX3<String>>(2 null,3 /// `Memo` stores the value resolved in cache,4 /// and retrieving that same value from the cache the next time5 /// it's needed instead of resolving it again.6 Memo.inline(7 (ArgsX3<String> args) async {8 final text = args.arg;9 final from = args.arg2;10 final to = args.arg3;11 // this is fake code, which simulates a request to API12 return await api.translate(text, from, to);13 },14 AsyncMemoSafe(), // avoid to save in cache when throw a error15 ),16);
Using when
method
UseAsyncState
provides a when
method that allows to computed a value depending on its status:
final result = uAsyncState.when( standby: (value) => "Standby", loading: (value) => "Loading", done: (value) => "Done", error: (error) => "Error: $error",);
print("Result: $result");
Updating the value
Use update
method to notify changes after run a set of instructions:
uAsyncState.update((value) { uAsyncState.value = "New value";});
Use refresh
method to force to notify changes.
uAsyncState.refresh();
Listening to changes
When value
has changed, the UseAsyncState
will emit the following events(learn about it here):
Lifecycle.willUpdate
event is triggered before thevalue
change orupdate
,refresh
methods have been invoked.Lifecycle.didUpdate
event is triggered after thevalue
change orupdate
,refresh
methods have been invoked.
Example of listening to changes:
1Rt.on(2 myAsyncState,3 Lifecycle.didUpdate,4 (_, state) => print("State value has changed to: ${state.value}"),5);