useAsyncSignal<T> function

AsyncSignal<T> useAsyncSignal<T>(
  1. AsyncState<T> value, {
  2. List<Object?> keys = const <Object>[],
  3. AsyncSignalOptions<T>? options,
})

Creates a new mutable AsyncSignal initialized with a specific AsyncState and subscribes to it.

Unlike useFutureSignal and useStreamSignal, an AsyncSignal exposes a mutable container where you can manually publish asynchronous states (e.g. AsyncState.loading(), AsyncState.data(...), or AsyncState.error(...)).

:::tip This is perfect for manually managed async workflows, like handling a login button click where you want to transitions states explicitly under your control. :::

Parameters

  • value: The initial AsyncState (e.g. AsyncState.loading() or AsyncState.data(initialValue)).
  • keys: A list of objects to watch. If any key changes, the async signal will be re-created.
  • debugLabel: An optional debug label.

Example

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:signals_hooks/signals_hooks.dart';

class LoginButton extends HookWidget {
  const LoginButton({super.key});

  @override
  Widget build(BuildContext context) {
    // Start in idle data state
    final loginState = useAsyncSignal<void>(AsyncState.data(null));

    Future<void> performLogin() async {
      loginState.value = AsyncState.loading();
      try {
        await apiLogin();
        loginState.value = AsyncState.data(null);
      } catch (err, stack) {
        loginState.value = AsyncState.error(err, stack);
      }
    }

    return loginState.value.map(
      data: (_) => ElevatedButton(
        onPressed: performLogin,
        child: const Text('Login'),
      ),
      error: (err, _) => Column(
        children: [
          Text('Error: $err', style: const TextStyle(color: Colors.red)),
          ElevatedButton(onPressed: performLogin, child: const Text('Retry')),
        ],
      ),
      loading: () => const CircularProgressIndicator(),
    );
  }
}

Implementation

AsyncSignal<T> useAsyncSignal<T>(
  AsyncState<T> value, {
  List<Object?> keys = const <Object>[],
  AsyncSignalOptions<T>? options,
}) {
  final s = useMemoized(() => asyncSignal(value, options: options), keys);
  return useExistingSignal(s, keys: keys);
}