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.