A simple way to access state while robust and testable for flutter

river_pod

A simple way to access state while robust and testable for flutter

A state-management library that:

  • catches programming errors at compile time rather than at runtime
  • removes nesting for listening/combining objects
  • ensures that the code is testable

This project can be considered as a rewrite of provider to make improvements
that would be otherwise impossible.

Long story short:

  • Declare your providers as global variables:

    final counterProvider = StateNotifierProvider((ref) {
      return Counter();
    });
    
    class Counter extends StateNotifier<int> {
      Counter(): super(0);
    
      void increment() => state++;
    }
    
  • Use them inside your widgets in a compile time safe way. No runtime exceptions!

    class Example extends ConsumerWidget {
      @override
      Widget build(BuildContext context, WidgetRef ref) {
        final count = ref.watch(counterProvider);
        return Text(count.toString());
      }
    }
    

Motivation

If provider is a simplification of InheritedWidgets, then Riverpod is
a reimplementation of InheritedWidgets from scratch.

It is very similar to provider in principle, but also has major differences
as an attempt to fix the common problems that provider face.

Riverpod has multiple goals. First, it inherits the goals of provider:

  • Being able to safely create, observe and dispose states without having to worry about
    losing the state on widget rebuild.
  • Making our objects visible in Flutter's devtool by default.
  • Testable and composable
  • Improve the readability of InheritedWidgets when we have multiple of them
    (which would naturally lead to a deeply nested widget tree).
  • Make apps more scalable with a unidirectional data-flow.

From there, Riverpod goes a few steps beyond:

  • Reading objects is now compile-safe. No more runtime exception.
  • It makes the provider pattern more flexible, which allows supporting commonly
    requested features like:
    • Being able to have multiple providers of the same type.
    • Disposing the state of a provider when it is no longer used.
    • Have computed states
    • Making a provider private.
  • Simplifies complex object graphs. It is easier to depend on asynchronous state.
  • Makes the pattern independent from Flutter

These are achieved by no longer using InheritedWidgets. Instead, Riverpod
implements its own mechanism that works in a similar fashion.

GitHub

https://github.com/rrousselGit/river_pod