riverpod
riverpod copied to clipboard
Alternatives to AVOID initializing providers in a widget
Respecting this don't in AVOID initializing providers in a widget.
class WidgetState extends State<MyWidget> {
@override
void initState() {
super.initState();
// Bad: the provider should initialize itself
ref.read(provider).init();
}
}
I have seen these 2 other ways to initialize a provider apart from Eager initialization.
I would like clarification if these 2 cases are okay or could lead to possible race conditions and unexpected behavior.
I've used before and seems to work fine, but I would like you to clarify this please.
Thanks.
Case 1: Initializing with addPostFrameCallback
in initState
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'main.g.dart';
@Riverpod(keepAlive: true)
class TextNotifier extends _$TextNotifier {
@override
String build() => 'build';
void init() async {
state = 'loading';
await Future.delayed(Duration(seconds: 2));
state = 'initiated';
}
}
void main() {
runApp(
ProviderScope(
child: MaterialApp(home: HomePage()),
),
);
}
class HomePage extends ConsumerStatefulWidget {
@override
ConsumerState<HomePage> createState() => _HomePageState();
}
class _HomePageState extends ConsumerState<HomePage> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
ref.read(textNotifierProvider.notifier).init();
});
}
@override
Widget build(BuildContext context) {
final text = ref.watch(textNotifierProvider);
return Center(child: Text(text));
}
}
Case 2: Initializing in the main and UncontrolledProviderScope
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'main.g.dart';
@Riverpod(keepAlive: true)
class TextNotifier extends _$TextNotifier {
@override
String build() => 'build';
void init() async {
state = 'loading';
await Future.delayed(Duration(seconds: 2));
state = 'initiated';
}
}
void main() {
final container = ProviderContainer();
container.read(textNotifierProvider.notifier).init();
runApp(
UncontrolledProviderScope(
container: container,
child: MaterialApp(home: HomePage()),
),
);
}
class HomePage extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final text = ref.watch(textNotifierProvider);
return Center(child: Text(text));
}
}