riverpod
riverpod copied to clipboard
A possibility to dispose the root container
When using a parent
container for the root ProviderScope
, it will not be disposed if we call runApp again with a different parent.
Using the parent
here is necessary for calling some async operations before running the app.
I think not auto-disposing the parent is reasonable, but is there another way to dispose the root container without declaring it globally?
I'm looking for something like:
ProviderScope.containerOf(context, rootContainer: true);
Example:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
Future<void> restartApp(BuildContext context) async {
scheduleMicrotask(() {
main();
print("app restarted");
});
}
void main() {
final container = ProviderContainer();
runApp(
ProviderScope(
key: UniqueKey(),
parent: container,
child: const TestApp(),
),
);
}
class TestApp extends ConsumerWidget {
const TestApp({
super.key,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
return const MaterialApp(
title: 'App',
home: HomeScreen(),
);
}
}
class HomeScreen extends ConsumerWidget {
const HomeScreen({
super.key,
});
@override
Widget build(BuildContext context, ref) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => const Page2()));
},
child: const Text('Go to Page2'),
),
),
);
}
}
class Page2 extends ConsumerWidget {
const Page2({super.key});
@override
Widget build(BuildContext context, ref) {
ref.watch(testProvider);
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () {
restartApp(context);
},
child: const Text("Restart"),
),
),
);
}
}
final testProvider = StreamProvider<String>(
(ref) async* {
print('init');
final timer = Timer.periodic(const Duration(seconds: 1), (timer) {
print(ref.hashCode);
});
ref.onDispose(() {
print('dispose');
timer.cancel();
});
yield "";
},
);
Using the parent here is necessary for calling some async operations before running the app.
No it isn't. No docs recommend putting init logic in the main. Instead it is recommended to use a ConsumerWidget at the root
I'm looking for something like:
ProviderScope.containerOf(context, rootContainer: true);
I don't see the relationship between this and disposing the root container. And this snippet isn't present in your example
So at the moment I'm not sure what you're requesting. The example you gave works today.
No it isn't. No docs recommend putting init logic in the main. Instead it is recommended to use a ConsumerWidget at the root
I get that and I actually have a ConsumerWidget
that act like a custom splash screen, but that screen still needs some information like the current locale/theme of the user which needs to be warmed-up during the native splash.
I don't see the relationship between this and disposing the root container. And this snippet isn't present in your example
So at the moment I'm not sure what you're requesting. The example you gave works today.
The example I gave is broken, with each restart
the previous parent
container won't be disposed.
I don't see the relationship between this and disposing the root container.
I'd be able to do the following at my restartApp method:
final rootContainer = ProviderScope.containerOf(context, rootContainer: true);
rootContainer.dispose();
The example I gave is broken, with each restart the previous parent container won't be disposed.
Keep a reference to it and dispose it then?
That's what i'm doing currently.
I was looking for a better and direct approach same as the rootNavigator
of Navigator class. I think this has a low priority.
I don't think I'll add such an API. It's too niche and you can already work around this on your own.