4

With riverpod_generator, I can use:

@riverpod
int foo(FooRef ref) => 0;

which is the equivalent of:

final fooProvider = Provider((ref) => 0);

But how can I do the same thing for other providers like FutureProvider, StateProvider, etc?

iDecode
  • 22,623
  • 19
  • 99
  • 186

2 Answers2

5

With code generation, you can use simplify your providers declaration. There are mainly five providers and you can see how to generate the equivalent code for each of them.

  1. Provider:

    The equivalent of

    final fooProvider = Provider((ref) => 0);
    

    is

    @riverpod
    int foo(FooRef ref) => 0;
    
  2. FutureProvider:

    The equivalent of

    final fooProvider = FutureProvider((ref) async {
      return 0;
    });
    

    is

    @riverpod
    Future<int> foo(FooRef ref) async {
      return 0;
    }
    
  3. StateProvider:

    The equivalent of

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

    is

    @riverpod
    class Foo extends _$Foo {
      @override
      int build() => 0;
    }
    
iDecode
  • 22,623
  • 19
  • 99
  • 186
1

First, install riverpod, exemple for flutter (because you can use riverpod only for Dart) :

flutter pub add flutter_riverpod dev:custom_lint dev:riverpod_lint riverpod_annotation dev:build_runner dev:riverpod_generator

'dev:custom_lint' and 'dev:riverpod_lint' are for code quality.

In your main.dart, add ProviderScode

/// For providers to work, you must add ProviderScope at the root of your Flutter applications:  
///source: https://riverpod.dev/docs/concepts/providers
    void main() {
      runApp(ProviderScope(child: MyApp()));
    }

Create a counter class for example (counter.dart)

import 'package:flutter/material.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

//add this line (standard configuration, you will got an error in vscode before you launch riverpod_generator because the file not existe yet)
part 'counter.g.dart';
// '@riverpod' annotation will be use by riverpod_generator
// to generate 'counterProvider' automatically

@riverpod
class Counter extends _$Counter {
  @override  
  int build() {
    // initial value de type int
    return 0;
  }

  void increment() {
    state++;
  }

  void decrement() {
    state--;
  }
}

Run riverpod_generator (it will become in background, and refresh after code modification to rebuild counter.g.dart (provider is inside this file) automatically

flutter pub run build_runner watch -d

And for the UI

//Extends ConsumerWidget to be able to access the counterProvider via ref.watch
class MyHomePage extends ConsumerWidget {
    class MyHomePage extends ConsumerWidget {
  const MyHomePage({super.key, required String title});

 @override
  // With ref you can access the provider
  Widget build(BuildContext context, WidgetRef ref) {
    //observe modification of provider
    final counter = ref.watch(counterProvider);

    
    //To access previous and current value, you can use listen
    ref.listen<int>(counterProvider, (previous, next) {
      print('prec : $previous | current valeur : $next');
    }, onError: (error, stackTrace) {});

    return Scaffold(
        appBar:
            AppBar(title: const Text('riverpod + riverpod_generator example')),
        body: Center(
            child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
              const Text('You have pushed the button this many times:'),
              //couter will update in real time !
              Text('$counter'),
            ])),
        floatingActionButton:
            Row(mainAxisAlignment: MainAxisAlignment.end, children: [
          FloatingActionButton(
              onPressed: () {
                
                //don't use ref.watch here (official documentation)                
                //ref.read(counterProvider.notifier).state--;
                //use ref.read after a user action (click on a button for example)
                ref.read(counterProvider.notifier).decrement();
              },
              tooltip: 'Decrement',
              child: const Icon(Icons.remove)),
          const SizedBox(width: 50),
          FloatingActionButton(
              onPressed: () {
                
                //ref.read(counterProvider.notifier).state++;
                ref.read(counterProvider.notifier).increment();
              },
              tooltip: 'Increment',
              child: const Icon(Icons.add))
        ]));
  }
    }}
rach
  • 129
  • 1
  • 5