[SOLVED] Strange behaviour for me on Flutter - initState executed once

Hello All
i’m new at flutter and I have strange behaviour
I have a HomeScreen which contain header - body - bottom Navigation Bar

bottom navigation bar contain ( home - notes - cart )
for Cart screen , I have Statefull widget , contain header and body

the body is pointing to third screen ( CartList.dart)

this page contain at initState , a print(‘this is message in CartList.dart’);

what I have noticed that , when I open the app , or when working with android studio and using hot restart , the print message is shown once , then when clicking on Cart , nothing is showing

can someone explain this behaviour , and tell me what is blocking to have the message to be shown always when I click on CART bottom menu
thank you

all screens are statefull widget , just fyi

initState do what the name implies: it initializes the state. The state will remain on memory while the widget is in the widget tree (not necessarily in view). It will only be executed once (that means your state is active in memory).

Hot restart will restart all states, hot reload will not.

If you don’t have a state in a widget, don’t use StatefulWidget. Things in Flutter has a reason to be (so build is meant ONLY to build widgets, initState is meant ONLY to initialize state… if you try to accomplish anything else on these methods, you’ll have problems. Some things won’t even work there, such as InheritedWidget (Theme.of(context),, MediaQuery.of(context) or any .of(context)).

1 Like

Thank you for your reply
I cannot change the screens to other than Statefull as they need to be statufull
The strange thing is that I wanted to reproduce it in fresh project , with same screens files ( home - cart , cartList ) and I have implement the print in initState in CartList
So when I run the app , the print did not show up,
Whenever I click on Cart menu , the print show up every time I click on Cart (expected)

So in my actual app , I do not know why there is this difference

As I told you , I want to achieve what is expected , whenever I click on the specific bottomNavBar menu , I have this print showing

The cart is running initState on each new creation. The parent screen stays alive in the navigator stack while the cart is shown. When the cart is popped, there’s no reason to init again, because it’s already alive.

1 Like

Thank you Randal , but still it is not clear to me why on fresh app , I can show the print message from initState everytime I click on Cart , but on my actual app not

In other word, how can I can make the following happen ?

Whenever I click on Cart Menu , I print a message , and the message defined from inside CartList.dat

Todo that you should choose a different approach like making your Cart a separate object which implements ChangeNotifier for instance and let your cart widget listen to changes inside that object.

Thanks
But could you explain why on sample app works as expected ? And i did reproduce the same screens and logic

Which sample app are you referring to?
And is your code available on github so we could have a look or paste the interesting pieces here (you can format them as code.

fixed it by simply
instead of
body: IndexedStack(
index: myIndex,
children: widgetList,
)

body: widgetList[myIndex]

1 Like

You didn’t “fix” anything, you just made a bad practice.

IndexedStack will keep all STATEFUL widgets alive (because they are, well, STATEFUL). Again, just because they are not on screen, it doesn’t mean they are not in memory (check DevTools widget’s tree).

What you are doing is forcefully adding/removing a widget from the tree, triggering a lot of widget, element and rendering trees rebuild. This is VERY bad for performance.

Again: initState is meant to initialize the ELEMENT tree (that’s what a BuildContext is). It is meant to initialize only once.

EVERY widget in Flutter is stateless (even the StatefulWidget). The only thing that changes is the Element (which BuildContext inherits). And that’s the difference between stateless and stateful: in stateless, the Element is generic and Flutter’s controlled. In stateful, it uses your Element (which is the State class).

Two trees, not related at all by what you see in your screen. (three, actually, but the rendering tree is irrelevant for this context).

Flutter is behaving like intended (and, BTW, initState is not meant to load data or do anything, EXCEPT INITIALIZE STATE). Do this in FutureBuilder, StreamBuilder or, if you wanna keep your sanity, MVVM.