Back to basic : Flutter widget lifecycle
Tags: flutter, widget, indonesia
Published: 2024-03-06 16:51:33

Flutter is a cross platform framework to build seamless user interface across all platforms, from web to mobile apps. Flutter introduces `Widget` as its main UI builder, we are living in the world of digital and reactive apps, so we need to understand how does Flutter app manage its `Widget` lifecycle.

## Quick review : Flutter's Widget
Based on Flutter official documentation, "Flutter widgets are built using a modern framework that takes inspiration from React. The central idea is that you build your UI out of widgets. Widgets describe what their view should look like given their current configuration and state."

So Widget is simply the object that build every piece of UI for Flutter. Each of widgets can have their own configuration and state, so if we build a page that consists of more than one widget, every widget will have their own lifecycle.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9jldn3sl7ndxztdioei8.png)

## Widget Lifecycle
Here are the order of Flutter widget's lifecycle : 

## 1. Initialization
This is the state where Flutter widget constructor is called. The object of the widget and state created. After the widget object is created, then it will call 2 kinds of framework functions, `initState()` and `didChangeDependencies()`. Details will be explained after this section.
## 2. Build
After state of the widget initialized and the context is already exists, then this time Flutter widget will build the UI. `build(BuildContext context)` framework function will be called here. The output of this step is the UI will be shown in our end user app.
## 3. State changes and rebuild
We know that the best app is an app that users can interact with. Flutter stateful widget have defined `state` as a mutable value that can be changed by app's/user's behavior/interaction. This step, Flutter will use `setState()`  framework function to change the state. After the state changes, the widget will be rebuilt with diffing algorithm to optimize build process.
## 4. Deactivate
Deactivate is the state where a widget is removed from widget tree temporarily or permanently. For example, if we have a stream where at some point we will destroy that widget but we'll need to use it again later.
## 5. Disposal
Disposal is the state where a widget is removed from widget tree permanently.

## Widget Lifecycle Framework Functions

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tw6fhbqe40t0vbqsm9wz.png)


### createState()
This method will create the State object under the widget. Usually this method exists on the widget if we create a stateful widget.
```
class StateLifecycleExample extends StatefulWidget {
  const StateLifecycleExample({super.key});

  @override
  State<StateLifecycleExample> createState() => _StateLifecycleExampleState();
}
```

### initState()
This method will be called only once when the state object is created for the first time. This method is executed before the `build()` function called. So we could say that this method had no access to widget's `BuildContext`. Usually we use this method to initialize some state's initial value or call some non-context related function to make sure those function ran on widget initialization process.
```
late int a,b,c;
  
@override
void initState() {
  a = <something manipulated>
  b = <something manipulated>
  c = <something manipulated>
  super.initState();
}
```

### didChangeDependencies()
This method will be called after initState(). We could access `BuildContext` here. Also, this method can be called multiple times based on dependencies that changed or object changes inside the widget. For example, if in one page we opened and closed a keyboard, then it would be counted as widget changed, so this method will be called.
```
@override
void didChangeDependencies() {
  print('this is didChangeDependencies, context : ${context} already exists here');
  super.didChangeDependencies();
}
```

### setState()
This method used to change state value and refresh the widget to show latest state of the widget. Fun fact, we don't have to put the changed value inside setState's callback function. So they would produce the same result. Why ? because setState will always rebuild the widget no matter how the callback function is.
```
a = 10;
setState((){})

and

setState((){
  a = 10
});
```

### deactivate()
Just like the definition above, "Deactivate is the state where a widget is removed from widget tree temporarily or permanently. For example, if we have a stream where at some point we will destroy that widget but we'll need to use it again later."

### dispose()
A bit different with deactivate, `dispose()` will be called only when the widget is removed from widget tree.

On that, we can see that `deactivate` and `dispose` are talking about removing widget from widget tree. Deactivate called when a widget removed temporary/permanently. But `dispose` called when widget removed permanently only. So if a widget is removed, `deactivate` and `dispose` will be called together.