Riverpod : Alternate way of overriding initState inside ConsumerWidget
Solution 1
Updated
Riverpod v1.0.0
You can use ConsumerStatefulWidget and ConsumerState
final helloWorldProvider = Provider((_) => 'Hello world');
class RiverpodExample extends ConsumerStatefulWidget {
@override
_RiverpodExampleState createState() => _RiverpodExampleState();
}
class _RiverpodExampleState extends ConsumerState<Example> {
@override
void initState() {
super.initState();
final value = ref.read(helloWorldProvider);
}
@override
Widget build(BuildContext context) {
final value = ref.watch(helloWorldProvider);
return Text(value); // Hello world
}
}
Up to Riverpod v0.14.0+3
You have to use StatefulWidget
and return Consumer as a root widget from the build
method.
Consumer
Consumer can be used to listen to providers inside a StatefulWidget or to rebuild as few widgets as possible when a provider updates.
final helloWorldProvider = Provider((_) => 'Hello world');
class RiverpodExample extends StatefulWidget {
@override
_RiverpodExampleState createState() => _RiverpodExampleState();
}
class _RiverpodExampleState extends State<Example> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Consumer(
builder: (context, watch, child) {
final value = watch(helloWorldProvider);
return Text(value); // Hello world
},
);
}
}
Solution 2
I'm not totally sure how to answer your question as I have not worked with ConsumerWidget. I'd presume the idea is to keep most of your state in providers.
However, I would like to recommend using hooks_riverpod alongside flutter_hooks (same developer).
This makes keeping state local to the widget simple and also provides easy access to providers.
For example:
class Example extends HookWidget {
const Example({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
final test = useProvider(Test.provider());
final controller = useTextEditingController();
final loading = useState(false);
final buttonText = useState('Change me!');
return Column(
children: [
TextField(controller: controller),
if (!loading) RaisedButton(
onPressed: () async {
loading.value = true;
await Future.delayed(const Duration(seconds: 1));
buttonText.value = controller.text;
loading.value = false;
}
child: Text(buttonText.value),
),
if (loading) const CircularProgressIndicator(),
// Do something with providers, etc.
],
),
);
}
Just a quick example, but there are plenty of resources (flutter_hooks, hooks_riverpod) to help you along. Also, check out examples from the developer on riverpod hooks usage.
towhid
Love to design and develop tools that help others to solve their problems.
Updated on November 21, 2022Comments
-
towhid over 1 year
What is the solution of initializing things inside consumerWidget as because the initState method is not overridable here?
-
towhid over 3 yearsYes, that could be a solution, but its completely overlooking the power of Riverpod / ConsumerWidget
-
Vinoth Vino over 3 yearsI don’t think any other way as of now @towhid
-
José Luna over 3 yearsAfter writing my code guided by your answer, I can conclude that this is the correct way to implement flutter_hooks with hook_riverpod and set variables at widget start up (and it's in the documentation). It's 'cause the initial values don't overwrite what you could set or update in the returned widget even though you rebuild it, so it's exactly like using initState.
-
Robert Mrobo over 2 years@wujek, the accepted answer by Vinoth did the trick for me. Try to follow it and see if you can come right even without the links. I think they are still updating the docs.
-
wujek over 2 yearsWhat's funny is that his links are just as broken as are mine, but at least he has inline code ;)
-
Alexa289 over 2 years@VinothVino it seems ConsumerStateMixin is no longer available on flutter_riverpod 1.0.0