preface

In the previous chapters, we conducted systematic consolidation learning from the basic components of Flutter to the higher-order components from shallow to deep, including data storage, network requests, page switching and value transfer through routing. After this series of knowledge system learning and consolidation, We have learned almost everything we need to know to get started with Flutter. Today we will build on the previous lessons and do a strengthening and improving share to explore the life cycle of Flutter components.

Course objectives

  • Understand the component lifecycle process
  • Understand the call timing and significance of each lifecycle callback function
  • Ability to align component lifecycles to improve business requirements

What is the component lifecycle

For example, Android, iOS, React, and Vue all have the concept of life cycle. It defines the entire existence process of a component from initialization, loading, intermediate state change, and destruction.

Based on the above flow chart, the life cycle segments defined in Flutter can be briefly summarized into three stages:

  • Initialize the
  • State changes
  • The destruction

2. Explain the existence significance of each life cycle stage

1. createState

CreateState is the method used to create a State in a StatefulWidget. When a new StatefulWidget is created, createState is executed immediately and only once. CreateState must implement:

class LifeCycleDemo extends StatefulWidget {
  @override
  State<StatefulWidget> createState(a) => _LifeCycleState();
}
Copy the code
2. initState

The previous createState method is called when the StatefulWidget is created, initState is the first method called after the StatefulWidget is created, and is executed only once. Similar to onCreate on Android, viewDidLoad() on IOS, so the View is not rendered, but the StatefulWidget is already loaded into the render tree, The StatefulWidget’s mount value will be true until Dispose calls it false. You can do some initialization in initState.

3. didChangeDependencies

When the StatefulWidget is first created, the didChangeDependencies method is called immediately after the initState method and not later when the StatefulWidget is refreshed. DidChangeDependencies will not be called until the InheritedWidget that your StatefulWidget depends on has changed, so didChangeDependencies may be called multiple times.

4. build

When StatefulWidget is first created, the Build method is called immediately after the didChangeDependencies method. Another scenario where the Build method is called is whenever the UI needs to be rerendered, So build gets called multiple times and returns the Widget to render. Never do anything in your build other than create widgets, as this will affect UI rendering efficiency.

5. didUpdateWidget

DidUpdateWidget is a life cycle that we don’t normally use and is called only when a Widget is reused using a key.

6. deactivate

When a State object is removed from the render tree, the DeActivate lifecycle is called, which signals that the StatefulWidget is about to be destroyed, but sometimes the State is not destroyed, but reinserted into the render tree.

7. dispose

When the View no longer needs to be displayed and is removed from the render tree, State is permanently removed from the render tree and Dispose life cycle is called. At this time, you can do some unlisten and animation operations in dispose, which is the opposite of initState.

3. Example code explanation

Let’s use a simple example to print a log to record that a component in A Flutter has been downloaded fromIs loadedtoState changesAnd to theHas been removedThe whole life cycle change process of.

The sample code
import 'package:flutter/material.dart';

class LifeCycleDemo extends StatefulWidget {
  @override
  State<StatefulWidget> createState(a) => _LifeCycleState();
}

class _LifeCycleState extends State<LifeCycleDemo> {

  var _count = 0;

  @override
  void initState(a) {
    super.initState();
    print('----------initState------------');
  }

  @override
  void didChangeDependencies(a) {
    super.didChangeDependencies();
    print('----------didChangeDependencies------------');
  }

  @override
  Widget build(BuildContext context) {
    print('----------build------------');
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            RaisedButton(
              child: Text('Close page'),
              onPressed: () => {Navigator.of(context).pop()},
            ),
            Text('Current count:'+_count.toString()),
            RaisedButton(
              child: Text('Refresh interface'),
              onPressed: () => {
                this.setState(() {
                  _count++;
                  print('---------- Refresh interface ------------'); })},)],),),); }@override
  void deactivate(a) {
    super.deactivate();
    print('----------deactivate------------');
  }

  @override
  void dispose(a) {
    super.dispose();
    print('----------dispose------------');
  }

  @override
  void didUpdateWidget(LifeCycleDemo oldWidget) {
    super.didUpdateWidget(oldWidget);
    print('----------didUpdateWidget------------'); }}Copy the code
3.1 When the page is loaded:

With the above code, we simulate that when a simple component is loaded onto the page, from initialization until the entire program is rendered, the component goes through the process frominitState–>didChangeDependencies–>buildIf the component does not update state to the operation at this time, the interface will remain in the state after build rendering is completed, and the log for each lifecycle callback function is printed as follows:

3.2 When a component is refreshed

We know that in FlutterStatefulWidgetthroughStateTo manage state changes throughout the page whenstateWhen a change occurs, the corresponding component is notified of the change. When the page state is updated, the build callback function in the lifecycle is called back and the interface is re-rendered, updating and rendering the changes to the UI.

As shown above, when I hit the refresh button twice, I change the value of _count by setState, and then the component senses the change in state and calls build again to refresh the interface until the new state is rendered on the UI.

The console prints the following log:

3. Components are uninstalled (destroyed)

When a page is destroyed, the component’s lifecycle state changes from deactivate–>dipose, which is usually clicked back or invoked by the userNavigator.of(context).pop()A callback occurred after the route was pushed out of the current page. In this case, you can cancel listening and animation based on service requirements.

3 conclusion

Through the introduction to the meaning of the various lifecycle functions, the reader can use the sample code of the above lifecycle tests to rewrite the sample code to get a sense of the meaning of the component lifecycle and when the different lifecycle callback functions are called back to deepen their understanding.