Ana içeriğe atla

Actions (experimental)

Actions are an imperative helper for running side-effects while temporarily keeping the providers used by that side-effect alive.

uyarı

Actions are experimental, and the API may change in a breaking way without a major version bump.

They are designed for callbacks such as button presses, commands, tests, or other event handlers where using watch would be inappropriate.

Riverpod exposes two top-level helpers:

  • action, which returns a value.
  • voidAction, a shorthand for actions that return void.

Running an action

Use an action from an imperative callback, then interact with providers through read.

class AddTodoButton extends ConsumerWidget {
const AddTodoButton({super.key});


Widget build(BuildContext context, WidgetRef ref) {
return ElevatedButton(
onPressed: voidAction(() async {
await ref.read(todoListProvider.notifier).addTodo('Eat a cookie');
}),
child: const Text('Add todo'),
);
}
}

If you need a result, use action instead:

Future<Todo> createTodo(WidgetRef ref, String title) {
return action(() {
return ref.read(todoListProvider.notifier).addTodo(title);
});
}

Keeping providers alive

While an action is pending, providers read or listened to from inside its callback stay alive until the action completes.

This is especially useful with autoDispose providers:

final currentUserProvider = FutureProvider.autoDispose<User>((ref) {
return ref.read(apiProvider).fetchCurrentUser();
});

Future<User> loadCurrentUser(ProviderContainer container) {
return action(() async {
return await container.read(currentUserProvider.future);
});
}

Without the action wrapper, an imperative read like this may allow the provider to dispose as soon as the read is no longer actively listened to.

Supported APIs inside actions

Actions are meant to work with imperative APIs:

  • ProviderContainer.read
  • Ref.read
  • WidgetRef.read
  • ProviderContainer.listen
  • Ref.listen
  • WidgetRef.listenManual

Subscriptions created by those listen APIs are automatically closed when the action ends.

APIs to avoid inside actions

Actions are not declarative, so watch-based APIs are intentionally not part of the pattern.

  • Use read instead of Ref.watch or WidgetRef.watch.
  • Use WidgetRef.listenManual instead of WidgetRef.listen.

If you need rebuilds driven by provider changes, stay in a declarative widget or provider context and use Consumers or

Refs APIs directly.

Actions vs mutations

Use actions when you simply want to perform imperative work while keeping the used providers alive.

Use Mutations (experimental) when the user interface should also react to the pending, error, or success state of that side-effect.