Riverpod : Alternate way of overriding initState inside ConsumerWidget

7,119

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.

Share:
7,119
towhid
Author by

towhid

Love to design and develop tools that help others to solve their problems.

Updated on November 21, 2022

Comments

  • towhid
    towhid over 1 year

    What is the solution of initializing things inside consumerWidget as because the initState method is not overridable here?

  • towhid
    towhid over 3 years
    Yes, that could be a solution, but its completely overlooking the power of Riverpod / ConsumerWidget
  • Vinoth Vino
    Vinoth Vino over 3 years
    I don’t think any other way as of now @towhid
  • José Luna
    José Luna over 3 years
    After 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
    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
    wujek over 2 years
    What's funny is that his links are just as broken as are mine, but at least he has inline code ;)
  • Alexa289
    Alexa289 over 2 years
    @VinothVino it seems ConsumerStateMixin is no longer available on flutter_riverpod 1.0.0