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를 통해 테스트를 진행했고 아래와 같이 콘솔에 순서대로 찍히는 것을 확인할 수 있습니다.
'App > Flutter' 카테고리의 다른 글
Flutter Redux 패턴에 대해 (0) | 2024.03.30 |
---|---|
Flutter로 만든 앱 aab 파일 추출하여 Google Play Store 업로드하기 (0) | 2024.03.16 |
Flutter Color 설정 방법 (0) | 2021.10.02 |
Flutter BuildContext에 대해 알아보기 (1) | 2021.07.10 |
Flutter Widget 및 디렉토리 구조 (0) | 2021.06.17 |
댓글