DEV Community

Cover image for Create a simple Flutter app with Riverpod v1.0.0
uuta
uuta

Posted on

Create a simple Flutter app with Riverpod v1.0.0

Riverpod

Riverpod is a Reactive State-Management and Dependency Injection Framework library on Flutter. Nov 5, 2021, the release date of version 1.0.0 has come, and modified some features. In this article, I'll try to describe how you would manage the state by Riverpod with simple application.

What is Riverpod?

  • No more ProviderNotFoundException
  • Provider inspires Riverpod but solves some of its key issues
  • No dependency on Flutter

Riverpod

Goal

Let's make a simple app that counts number per pushing a button.

Image description

Environment

dependencies:
  flutter:
    sdk: flutter
  riverpod: ^1.0.0
  flutter_hooks: ^0.18.0
  hooks_riverpod: ^1.0.0
Enter fullscreen mode Exit fullscreen mode

1. Update state with StateNotifierProvider

Use StateNotifierProvider , StateNotifier , HookConsumerWidget to update and read state.

2. Import packages

import 'package:flutter/material.dart';
import 'package:riverpod/riverpod.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
Enter fullscreen mode Exit fullscreen mode

3. Define countStateProvider variable with StateNotifierProvider

StateNotifierProvider is combined with StateNotifier .

StateNotifierProvider class - riverpod library - Dart API

final countStateProvider =
    StateNotifierProvider<CountState, int>((ref) => CountState(0));
Enter fullscreen mode Exit fullscreen mode

4. Set up CountState class with StateNotifier

StateNotifier is an observable class that stores a single immutable state. At first, create CountState class extended StateNotifier class.

class CountState extends StateNotifier<int> {
  CountState(int count) : super(count);

  void increment() => state = state + 1;
}
Enter fullscreen mode Exit fullscreen mode

StateNotifier is designed to be subclassed. You first need to give an initial value to the super constructor. In the above, CountState class receives the count argument, and then passes it to the super constructor.

CountState(int count) : super(count);
Enter fullscreen mode Exit fullscreen mode

The next shows the published method to allow other objects modify to modify the counter.

void increment() => state = state + 1;
Enter fullscreen mode Exit fullscreen mode

It is possible to define multiple methods in StateNotifier class.

void increment() => state++;
void decrement() => state--;
Enter fullscreen mode Exit fullscreen mode

5. ProviderScope on Riverpod

All applications dealing with Riverpod must contain a ProviderScope at the root of your widget tree. Thus, let's wrap MyApp class defined next chapter by ProviderScope.

void main() {
  runApp(ProviderScope(
    child: MyApp(),
  ));
}
Enter fullscreen mode Exit fullscreen mode

6. MyAPP with HookConsumerWidget

Let's make a MaterialApp in MyApp class extending HookConsumerWidget, the alternative of HookWidget, released after version 1.0.0.

class MyApp extends HookConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final int count = ref.watch(countStateProvider);

    return MaterialApp(
      home: Scaffold(
        body: Center(child: Text('$count')),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            ref.read(countStateProvider.notifier).increment();
          },
        ),
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

To watch the state in countStateProvider, define the count variable with ref.watch(), replaced from useProvider on the previous version.

Widget build(BuildContext context, WidgetRef ref) {
  final int count = ref.watch(countStateProvider);
Enter fullscreen mode Exit fullscreen mode

Add ref.read() to call increment() function in CountState for when pressing floatingActionButton.

onPressed: () {
  ref.read(countStateProvider.notifier).increment();
},
Enter fullscreen mode Exit fullscreen mode

7. Whole code

import 'package:flutter/material.dart';
import 'package:riverpod/riverpod.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

final countStateProvider =
    StateNotifierProvider<CountState, int>((ref) => CountState(0));

class CountState extends StateNotifier<int> {
  CountState(int count) : super(count);

  void increment() => state = state + 1;
}

void main() {
  runApp(ProviderScope(
    child: MyApp(),
  ));
}

class MyApp extends HookConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final int count = ref.watch(countStateProvider);

    return MaterialApp(
      home: Scaffold(
        body: Center(child: Text('$count')),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            ref.read(countStateProvider.notifier).increment();
          },
        ),
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)