Files
2022-10-10 08:58:58 +02:00

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 customizable
  • ref.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 the Listenable interface (as required by GoRouter's refreshListenable parameter);
  • A ref object must be piped down to ChangeNotifier: 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!