1.9 KiB
sync_router
This example uses synchronous redirects while exploiting a ChangeNotifier
as a Listenable
object inside our Router definition.
Dependencies:
- GoRouter v5
- Riverpod v2
Is this approach advised?
This example just works. It has its downside (see below), but it correctly exploits GoRouter's API, while still maintaining Riverpod's advantages.
Advantages:
RouterNotifier
centralizes all the logic, which can be highly customizableref.listen
allows to scale reactive dependencies linearly- No side effects
Disadvantages:
ChangeNotifier
is discouraged within Riverpod (see https://riverpod.dev/docs/concepts/providers/#different-types-of-providers), but it's the closest class we have at our disposal that implements theListenable
interface (as required byGoRouter
'srefreshListenable
parameter);- A
ref
object must be piped down toChangeNotifier
: this might be undesirable, as this causes a small caveat (see below)
Short explanation
In this example we directly implement a ChangeNotifier
. In its constructor method, we exploit ref.listen
to add reactive dependencies through notifyListeners
.
Caveat
Reactive dependencies must be defined only within the constructor and only through ref.listen
.
This is key to avoid unnecessary rebuilds: when writing logic inside our Notifier, we might want to use ref.read
to read providers, and avoid ref.watch
.
GoRouter is already aware of state changes through refreshListenable
: we don't want to trigger a rebuild of the surrounding provider.
Simply put - this is not clean code - this works because of side effects.
Getting started
First, read the code:
- 'lib/main.dart' has UI elements
- 'lib/router.dart' has the routing logic
- 'lib/auth.dart' has the auth logic
Most of the actions are mocked, here. Then, run:
flutter test
flutter run
Enjoy!