Here is an example using Flutter Hooks and Riverpod.
I define a FutureProvider to fetch the weights from the server:
final weightsProvider = FutureProvider((ref) => findAllWeights());
Future<List<double>> findAllWeights() async {
print('FETCHING DATA'); // This gets run only once
final random = Random();
await Future.delayed(Duration(seconds: 2));
return List.generate(20, (index) => 50 + 20 * random.nextDouble());
}
And then, I use the result in both my WidgetOne
to calculate the SUM and my WidgetTwo
to calculate the AVERAGE. As you will see, the FETCHING DATA
only happens once.
Full source code
import 'dart:math' show Random;
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/all.dart';
void main() {
runApp(
ProviderScope(
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
home: HomePage(),
),
),
);
}
final weightsProvider = FutureProvider((ref) => findAllWeights());
Future<List<double>> findAllWeights() async {
print('FETCHING DATA'); // This gets run only once
final random = Random();
await Future.delayed(Duration(seconds: 2));
return List.generate(20, (index) => 50 + 20 * random.nextDouble());
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
WidgetOne(),
WidgetTwo(),
],
),
);
}
}
class WidgetOne extends HookWidget {
@override
Widget build(BuildContext context) {
final weights = useProvider(weightsProvider);
return Card(
child: Column(
children: [
Text('SUM of the weights'),
weights.when(
data: (data) => Text(data.reduce((a, b) => a + b).toString()),
loading: () => CircularProgressIndicator(),
error: (_, __) => Text('Something bad happended'),
),
],
),
);
}
}
class WidgetTwo extends HookWidget {
@override
Widget build(BuildContext context) {
final weights = useProvider(weightsProvider);
return Card(
child: Column(
children: [
Text('AVERAGE of the weights'),
weights.when(
data: (data) =>
Text((data.reduce((a, b) => a + b) / data.length).toString()),
loading: () => CircularProgressIndicator(),
error: (_, __) => Text('Something bad happended'),
),
],
),
);
}
}
I used Riverpod in this examples but there are other State Management, check here for a curated List of state management approaches.
Update for Riverpod 1.0
import 'dart:math' show Random;
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
void main() {
runApp(
const ProviderScope(
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
home: HomePage(),
),
),
);
}
final weightsProvider = FutureProvider((ref) => findAllWeights());
Future<List<double>> findAllWeights() async {
print('FETCHING DATA'); // This gets run only once
final random = Random();
await Future.delayed(const Duration(seconds: 2));
return List.generate(20, (index) => 50 + 20 * random.nextDouble());
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: const [
WidgetOne(),
WidgetTwo(),
],
),
);
}
}
class WidgetOne extends HookConsumerWidget {
const WidgetOne({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final weights = ref.watch(weightsProvider);
return Card(
child: Column(
children: [
const Text('SUM of the weights'),
weights.when(
data: (data) => Text(data.reduce((a, b) => a + b).toString()),
loading: () => const CircularProgressIndicator(),
error: (_, __) => const Text('Something bad happended'),
),
],
),
);
}
}
class WidgetTwo extends HookConsumerWidget {
const WidgetTwo({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final weights = ref.watch(weightsProvider);
return Card(
child: Column(
children: [
const Text('AVERAGE of the weights'),
weights.when(
data: (data) =>
Text((data.reduce((a, b) => a + b) / data.length).toString()),
loading: () => const CircularProgressIndicator(),
error: (_, __) => const Text('Something bad happended'),
),
],
),
);
}
}