1. Stateless Widget : They do not change their state throughout the lifetime of your application. They are like a constant widget.
2. Stateful Widget: They are dynamic, they change their state based on the External Interactions.
A side note: Stateless widgets can change their state if some state management tools are used like Provider, Bloc, etc
But thatโs out of the scope of this thread.
Letโs continue ๐๐ป
Letโs start with Stateful widgets. Itโs life-cycle has 8 stages:
1. createState()
2. initState()
3. didChangeDependencies()
4. build()
5. didUpdateWidget()
6. setState()
7. deactivate()
8. dispose()
Letโs dive in ๐คฟ
1. createState
This is the first method that is called when you create a Stateful widget. It returns an instance of the State associated with it.
Written inside the class that extends StatefulWidget.
2. initState
This is the first method called after the widget is created. It is called only once during the entire lifetime. It is used to initialize the data that can change on the widget.
It is used to initialise controllers like AnimationController, or even Futures.
3. didChangeDependencies
This method is called immediately after initState and when dependency of the State object changes via InheritedWidget.
So, what is the difference between initState and didChangeDependencies ?
initState is called before the state loads any dependencies, due to which context is not available inside initState.
Also, we cannot call initState again and again to update variables.
didChangeDependencies is called just a few moments after the state loads its dependencies and context is available at this moment so here you can use context.
And also we can call this method any number of times to update/initialise our data.
4. build
This is where the actual widgets get rendered onto the screen. It returns the widget to be displayed.
This method is called often to refresh the ui to support dynamic changes due to user interactions or external data.
5. didUpdateWidget
This method is called every time there is a change in configuration for a given widget.
This could be something like a change in data passed through constructor from parent to child.
Let me explain this with an example:
Imagine you have a variable โtitleโ in the Stateful class and you update it in your State class.
The change can be detected using the code below:
oldWidget points to the previous version of the Stateful widget. The title variable is compared to check if it has changed recently.
This is the main purpose of using didUpdateWidget. It checks for change in dependencies, ie, the data passed through constructor from parent.
6. setState
This is a very popular method in Flutter. You use it to update the state of your widget.
Every time this is run, it re-renders the build method and the changes are reflected in the UI.
It is an error to call this method after the framework calls dispose.
7. deactivate
It is called when the object is removed from the tree, but donโt dispose your widgets here.
It is called when you move your widget in the tree using GlobalKey
8. dispose
It is the opposite of initState. Its the last method called during the entire life cycle. It is used to dispose any variables like controllers to avoid memory leaks.
Well, thatโs about Stateful widget. Letโs come to Stateless widget.
It has only one method:
1. build()
It renders the stateless widget. Thatโs all ๐
Well, thatโs basically about the lifecycle of a widget in Flutter.
Hope you liked it. Do let me know if I made any mistakes anywhere, I will be happy to rectify that!
Every time your UI refreshes (eg: using a setState), the future method is run again, which can turn out to be very expensive!
Sometimes this could be helpful, but most of the times itโs a curse for the application.
So how can you fix it ?
๐๐ป
We need to set the future in such a way that its run only once, and will never run again until you re-open the screen or you explicitly define a Swipe-down-to-refresh feature.
So, what is that one thing in Flutter, which will run only once in the entire life-cycle of your screen