mutation<T> method
Allows you to trigger and watch Futures (called mutations, since they often mutate some state) from within the build function. See the documentation for more.
Note: mutate()
and clear()
should not be called directly from
within build, but rather from within some callback.
Implementation
Mutation<T> mutation<T>() {
final (getValue, setValue) = use.data<AsyncValue<T>?>(null);
// NOTE: we convert to a stream here because we can cancel
// a stream subscription; there is no builtin way to cancel a future.
final (future, setFuture) = use.state<Future<T>?>(null);
final asStream = use.memo(() => future?.asStream(), [future]);
use.effect(
() {
setValue(
asStream == null ? null : AsyncLoading(getValue()?.data ?? None<T>()),
);
final subscription = asStream?.listen(
(data) => setValue(AsyncData(data)),
onError: (Object error, StackTrace trace) => setValue(
AsyncError(error, trace, getValue()?.data ?? None<T>()),
),
);
return () => subscription?.cancel();
},
[asStream],
);
return (
state: getValue(),
mutate: setFuture,
clear: () => setFuture(null),
);
}