본문 바로가기
App/Flutter

Flutter 위젯의 생명주기(Widget Lifecycle)

by Day0404 2021. 6. 23.
728x90
반응형

출처 : https://ko.wikipedia.org/wiki/%ED%94%8C%EB%9F%AC%ED%84%B0

Flutter 위젯의 생명주기

위젯의 생명주기를 알면 언제 데이터를 주고받을지, 그리고 화면이 사라질 때 어떤 로직을 처리해야 할지를 정리해서 넣을 수 있습니다. 예를 들어 특정 화면에서 숫자를 계속 올려주는 증가시켜준다고 했을 때 화면을 종료해도 계속 증가가 되면 안 되기 때문에 이런 상황을 막기 위해 화면이 종료될 때 숫자가 증가하는 것도 멈추는 기능을 넣어야 합니다.

예를 들어 스프링 프레임워크를 공부할 때 Bean의 생명주기를 모르고 사용하면 이해하기 힘들듯이 Flutter도 위젯의 생명주기를 알고 사용하는 것이 반드시 필요하다고 생각합니다.

 

StatefulWidget

StatelessWidget 위젯의 경우 한 번 생성되면 갱신할 수 없으므로 생명주기가 없습니다.

다른 화면으로 전환 시 모든 로직이 종료됩니다. 그러나 StatefulWidget 위젯은 총 8단계로 구분하는 생명주기가 있습니다.

 

1. createState()

StatefulWidget 클래스를 상속받는 클래스는 반드시 createState() 함수를 호출해야합니다.

이 함수는 다른 생명주기 함수들이 포함된 State 클래스를 반환합니다.

위젯의 상태를 생성하는 함수입니다.

class MyHomPage extends StatefulWidget {
  const MyHomPage({Key? key}) : super(key: key);

  @override
  _MyHomPageState createState() => _MyHomPageState();
}

class _MyHomPageState extends State<MyHomPage> {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

createState() 함수가 호출되어 State가 생성되면 mounted 속성이 true로 변경됩니다.

mounted 속성이 true라는 것은 위젯을 제어할 수 있는 BuildContext 클래스에 접근할 수 있다는 의미입니다.

이 BuildContext가 활성화되어야 setState() 함수를 사용할 수 있습니다.

if (mounted) {
  print('True'); // true
}

 

2. initState()

initState() 함수는 위젯을 초기화할 때 한 번만 호출합니다.

말 그대로 초기화하는 함수이기 때문에 별 다른 설명은 하지 않겠습니다.

initState() 함수를 호출할 때 서버에서 받아온 데이터를 화면에 출력하게 만들 수 있습니다.

@override
initState() {
  super.initState();
  // TODO
}

3. didChangeDependencies()

위젯을 초기화하는 initState() 함수가 호출된 뒤 바로 호출되는 함수가 didChangeDependencies() 함수입니다.

데이터에 의존하는 위젯은 화면에 데이터를 표시하기 전에 호출해야 합니다.

 

4. build()

이 함수는 위젯을 반환합니다.

build() 함수에서 위젯을 만들고 반환하면 화면에 표시됩니다. 필수적으로 override 해야 합니다.

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter App Test',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }

5. didUpdateWidget()

부모 위젯이나 데이터가 변경되어 위젯을 갱신해야 할 때 호출합니다.

initState() 함수는 위젯을 초기화할 때 한 번만 호출되므로 위젯이 변경되었을 때 호출하는 didUpdateWidget() 같은 함수가 필요합니다.

@override
void didUpdateWidget(Widget oldWidget) {
  if (oldWidget.importantProperty != widget.importantProperty) {
    _init();
  }
}

 

6. setState()

setState() 함수를 이용하여 데이터가 변경되었다는 것을 인지하고 변경된 데이터를 이용해 UI를 변경할 수 있도록 합니다. Flutter를 이용해 앱을 만들 때 많이 호출하는 함수 중 하나입니다.

 

7. deactivate()

deactivate() 함수는 State 객체가 Flutter의 구성 트리로부터 제거될 때 호출됩니다.

하지만, State 객체가 제거됐다고 해서 메모리까지 지워지지는 않기 때문에 dispose() 함수를 호출하기 전까지는 State 객체를 사용할 수 있습니다.

 

8. dispose()

State 객체를 소멸할 때 호출합니다. 이 함수를 호출하는 것은 해당 위젯을 종료하겠다는 의미입니다.

네트워크 통신을 하다가 dispose() 함수를 호출하면 데이터 전송을 중지합니다.

위젯을 소멸할 때 꼭 호출해야 하는 함수가 있다면 이 dispose() 함수 내에서 호출하면 됩니다.

 

아래는 생명주기 순서를 호출하는 예제입니다.

간단한 예제이기에 전체 생명주기에 대해 호출하지는 않습니다.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    print('createState');
    return _MyAppState();
  }
}

class _MyAppState extends State<MyApp> {

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

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

  @override
  Widget build(BuildContext context) {
    print('build');
    return Container();
  }
}

 

저는 intelliJ를 통해 테스트를 진행했고 아래와 같이 콘솔에 순서대로 찍히는 것을 확인할 수 있습니다.

 

반응형

댓글