Stateful widget consumer widget builds twice and hence calls initState twice. How to stop this from happening?
Asked Answered
P

0

7

So for my project, I am using Riverpod, and I am creating the home page of my app. The tree looks like this ->

CommunityView(Stateful Widget)
WillPopScope
ProviderScope
Consumer
Scaffold
...and so on

Now inside the build method of the CommunityView Widget,

 final params = _VSControllerParams(
      selectedFamily: widget.selectedFamily,
    );
    print('familiesStatus: rebuild main');

    return WillPopScope(
      onWillPop: onWillPop,
      child: ProviderScope(
        overrides: [_paramsProvider.overrideWithValue(params)],
        child: Consumer(
          builder: (context, watch, child) {
            print('familiesStatus: rebuild consumer');
            final state = watch(_vsProvider(params));
            final stateController = watch(_vsProvider(params).notifier);

The rebuild main print happens only once, while the rebuild consumer print happens twice. Previously home page fetched data and then shows data fetched or error depending on network response. Now I use an enum to get loading state, i.e. ApiStatus.loading is the initial state, then ApiStatus.success or failure depending on response. Now what I have changed that is causing this issue is -> I have added a function call in initstate that fetches local saved cache and loads data from that. So what happens is ApiStatus.loading->ApiStatus.success(Cache fetched)->ApiStatus.loading(somehow whole widget rebuild)->ApiStatus.success(cache fetched again)->ApiStatus.success(Data fetched from internet). So I am not sure why it is rebuilding first time when cache is fetched.

Now to fix this, I first tried to find any reason in the cache method call that is causing this rebuild, but was not able to find any even with heavy debugging. Then I thought to create a global parameter which is something like this

bool fetchDataFromCache = true;

and then inside initState, I call fetch Cache method something like this

if(fetchDataFromCache){
    fetchCache();
    fetchDataFromCache = false;
}

But this caused the ApiStatus loading parameter to change like this ->ApiStatus.loading(initial build)->ApiStatus.success(Cache fetched)->ApiStatus.loading(somehow whole widget rebuild)->ApiStatus.success(Data fetched from internet). So widget is still rebuilding because I have set ApiStatus.loading only in initState, and nowhere else. So it is still glitching out.

Demo video - https://youtu.be/1EzYfCRiwk0

Pinole answered 22/3, 2022 at 16:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.