Skip to content

Instantly share code, notes, and snippets.

@josh-burton
Last active August 15, 2022 19:56
Show Gist options
  • Save josh-burton/5184e6b4702f5d82040194cab308bc46 to your computer and use it in GitHub Desktop.
Save josh-burton/5184e6b4702f5d82040194cab308bc46 to your computer and use it in GitHub Desktop.
Riverpod StateProvider select vs watch

Riverpod StateProvider select vs watch

Created with <3 with dartpad.dev.

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
void main() {
runApp(
const ProviderScope(child: MyApp()),
);
}
final sourceProvider = StateProvider((ref) => 0);
final watchProvider = FutureProvider<int>((ref) async {
// I would expect that this provider would only update when the value of sourceProvider
// changes.
// Instead it updates whenever the sourceProvider updates, even when the value is equal to the previous
// value
final source = ref.watch(sourceProvider);
await Future.delayed(const Duration(seconds: 2));
return source;
}, dependencies: [
sourceProvider,
]);
final selectProvider = FutureProvider<int>((ref) async {
// this provider uses select to prevent unncessary rebuilds when the updated value is the same
final source = ref.watch(sourceProvider.select((v) => v));
await Future.delayed(const Duration(seconds: 2));
return source;
}, dependencies: [
sourceProvider,
]);
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends ConsumerWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
appBar: AppBar(
title: const Text('Riverpod example'),
),
body: Row(
children: [
Expanded(
child: ContentWidget(data: ref.watch(watchProvider)),
),
Expanded(
child: ContentWidget(data: ref.watch(selectProvider)),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () => ref.refresh(sourceProvider),
tooltip: 'Refresh',
child: const Icon(Icons.refresh),
),
);
}
}
class ContentWidget extends ConsumerWidget {
final AsyncValue<int> data;
const ContentWidget({Key? key, required this.data}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
return Center(
child: data.map(
data: (it) => Text(it.value.toString()),
loading: (it) => const Text("Loading"),
error: (error) => const Text("error"),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment