---
name: riverpod-refs-6aac7595365a
description: Use Ref and WidgetRef to read, watch, listen, invalidate, and refresh providers; onDispose and onCancel lifecycle; ref.read vs ref.watch vs ref.listen, ref.invalidate and ref.refresh. Use when interacting with Riverpod providers from widgets or other providers, when to use watch vs read, or when resetting provider state. Use this skill whenever the user asks about ref.watch, ref.read, ref.listen, ref.invalidate, or Riverpod lifecycle.
---

# Riverpod — Refs

## Instructions

**Ref** (and **WidgetRef** in widgets) is how you interact with providers: read state, listen to changes, reset state, and register lifecycle callbacks. Providers get a `Ref` as the first parameter of their function or as `this.ref` in a Notifier. Widgets get a **WidgetRef** via Consumer / ConsumerWidget / ConsumerState.

### Obtaining a Ref

- **Inside a provider:** First parameter of the provider function, or `ref` property in a Notifier.
- **Inside a widget:** Use a Consumer (builder gives `ref`), ConsumerWidget (`build(context, ref)`), or ConsumerStatefulWidget (state has `ref`). Pass `ref` to other functions if needed.

### Listening to state

- **ref.watch(provider)** — Declarative. Your widget/provider rebuilds when the provider changes. Use this by default in build methods.
- **ref.listen(provider, (prev, next) { ... })** — Imperative. Run side effects when the provider changes (e.g. show a dialog, navigate). Safe to use in build; for initState use `ref.listenManual` and manage the subscription.

```dart
// In a widget
final tick = ref.watch(tickProvider);
return Text('Tick: $tick');

// Side effect when provider changes
ref.listen(tickProvider, (previous, next) {
  print('Tick changed from $previous to $next');
});
```

### Reading without listening

- **ref.read(provider)** — Get current value without subscribing. Use in event handlers (e.g. onPressed), not to "optimize" by avoiding watch. For selective rebuilds use `ref.watch(provider.select((value) => ...))`.

```dart
onPressed: () {
  final tick = ref.read(tickProvider);
  print('Current tick: $tick');
}
```

### Resetting state

- **ref.invalidate(provider)** — Discard current state; provider will recompute on next read. If the provider is listened to, a new state is created.
- **ref.refresh(provider)** — Same as invalidate + read: invalidates and returns the new value. Use when you need the new value immediately.

```dart
ref.invalidate(tickProvider);
// or
final newTick = ref.refresh(tickProvider);
```

### Lifecycle: onDispose, onCancel

Inside a provider you can register callbacks:

- **ref.onDispose(callback)** — Called when the provider state is destroyed (e.g. auto-dispose or recomputation). Use to close StreamControllers, cancel timers, etc. Do not trigger side effects that modify other providers inside onDispose.
- **ref.onCancel(callback)** — Called when the last listener is removed (before dispose). **ref.onResume(callback)** — Called when a listener is added again after onCancel.

```dart
final provider = StreamProvider<int>((ref) {
  final controller = StreamController<int>();
  ref.onDispose(controller.close);
  return controller.stream;
});
```

You can call onDispose multiple times (e.g. one per disposable resource). Return value of onDispose/onCancel can be called to unregister. For more detail and select/listenManual, see [reference.md](reference.md).


---
Source attribution: dangdungvn
Original project: https://github.com/dangdungvn/review_system_app/blob/f397d2abe0a8d4c041cd274f0ffc5680d85e7c44/.github/skills/riverpod-refs/SKILL.md
License: MIT
License information: https://opensource.org/license/mit
Original upstream instructions; downloaded from Dave AI.

## Upstream license notice

MIT License

Copyright (c) 2024 Minh Nguyen

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.



# Dave AI resource metadata

Creator / publisher: dangdungvn
Original project: https://github.com/dangdungvn/review_system_app/blob/f397d2abe0a8d4c041cd274f0ffc5680d85e7c44/.github/skills/riverpod-refs/SKILL.md
Attribution basis: Source repository record

Fields of work: Development & Engineering, Product Management
Roles: Frontend Developer, Mobile Developer, Product Manager
Specialties: Frontend, Mobile
Tools: Riverpod
Country applicability: Country not specified
Classification basis: Source catalog labels
Instruction SHA-256: e1bebedd617cd12ac6dcf1d264b3c0af6e8743be907707613278e77757cb0a54
