What is better, Riverpod or provider

In the flutter community, many developers think Riverpod is better than Provider, which is an earlier-released-state-management package. However, flutter creators still recommend Provider as the stable state management mechanism at the time of writing this post.

According to the creator of both packages, Remi Rousselet, and other flutter developers as well, Provider has had some limitations. Riverpod has overcome those limitations.

Certainly, provider is a wrapper class or rather a kind of simplification of InheritedWidgets. On the contrary, Remi Rousselet has re-implemented InheritedWidget from the scratch and made Riverpod.

Both the state management packages have similarity and also has many differences.

As a state management package, provider has become enormously popular. Then why do we need another mechanism in place?

Provider can create, observe and dispose state without rebuilding widgets. It makes objects visible in Flutter’s devtool. Testing and composing is not difficult. Since the data flow is unidirectional, the app is scalable.

These are all advantages that has made provider package so popular.

However, Riverpod has extended these benefits in a great way. It is compile-safe. It doesn’t throw any run time exception. With riverpod we can have multiple providers of same type. It can make a provider private.

Above all, Riverpod is flutter independent as we can achieve the above mentioned features by not using InheritedWidgets any more. Riverpod implements its own mechanism.

What is new in Riverpod?

Firstly, we need to add the latest dependency.

dependencies:
  flutter:
    sdk: flutter
  provider: ^6.0.0
  flutter_riverpod: ^1.0.0-dev.11

Secondly, we can wrap our root with ProviderScope.

void main() {
  runApp(
    const ProviderScope(
      child: ProviderAppSample(),
    ),
}

From now on, all the providers we’ll create, the ProviderScope will store the state of them.

The new concept in the latest Riverpod is the ref object of type WidgetRef.

What is a WidgetRef?

In the latest Riverpod, we can watch or read provider’s value by using this ref object.

When we use Consumer or ConsumerState, the WidgetRef object is available as an argument, and it can interact with any provider.

As the BuildContext allows us to access the ancestor widgets in the widget tree, the WidgetRef does the same, allowing us to interact with any provider.

How does that happen?

Because all Riverpod providers are global so that we can access them easily. As a result, we can handle state management logic outside the widget tree.

We need to remember that Provider does not let us change the value. To do that we need to create a StateProvider. It will be a global value.

final referenceValue = StateProvider((ref) => 0);

Now, we can watch and read the provider’s value quite easily.

import 'package:flutter/material.dart';

import 'package:flutter_riverpod/flutter_riverpod.dart';

class ProviderAppSample extends StatelessWidget {
  const ProviderAppSample({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: ProviderHome(),
    );
  }
}

final referenceValue = StateProvider((ref) => 0);

class ProviderHome extends ConsumerWidget {
  const ProviderHome({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final counterWatch = ref.watch(referenceValue);
    final counterRead = ref.read(referenceValue);
    return Scaffold(
      body: Center(
        child: Column(
          children: [
            Container(
              margin: const EdgeInsets.all(20),
              padding: const EdgeInsets.all(20),
              child: Text(
                '${counterWatch.state}',
                style: const TextStyle(
                  fontSize: 100,
                  fontFamily: 'Allison',
                  fontWeight: FontWeight.bold,
                  color: Colors.red,
                ),
              ),
            ),
            const SizedBox(
              height: 20,
            ),
            ElevatedButton(
              onPressed: () => counterRead.state++,
              child: const Text(
                'Press to Increment',
                style: TextStyle(
                  fontSize: 30,
                  color: Colors.white,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

And we can access the provider’s state quite easily.

Widget build(BuildContext context, WidgetRef ref) {
    final counterWatch = ref.watch(referenceValue);
    final counterRead = ref.read(referenceValue);
...

And after that, we can either watch the change, and implement the change.

 child: Text(
                '${counterWatch.state}',
...
ElevatedButton(
              onPressed: () => counterRead.state++,
...

As a result, we can see the following screenshots.

Riverpod Provider watch
Riverpod Provider watch
Riverpod Provider read
Riverpod Provider read

What Next?

Books at Leanpub

Books in Apress

My books at Amazon

GitHub repository

Technical blog

Twitter


Posted

in

, , , ,

by

Comments

One response to “What is better, Riverpod or provider”

  1. […] What is better, Riverpod or provider […]

Leave a Reply