-
스나이퍼팩토리 8일차 과제2카테고리 없음 2023. 2. 4. 02:34
Stateful위젯의 라이프사이클
StatefulWidget에는 lifecycle(생명주기)이 존재한다. flutter 앱에서는 위젯의 생성부터 파기까지의 위젯의 생명주기가 관리 되어지고 있고, 생명주기의 특정 시점에서 특정메소드가 호출되어진다. 이러한 라이프사이클의 상태를 이해함으로써 위젯의 정교한 제어가 가능해진다. 위젯을 만들 때 우리가 잘 인식하지않고 사용하고 있는 build 메소드나 initState메소드 역시 라이프사이클과 관련된 메소드이다.
라이프 사이클 메소드
라이프사이클에는 대략적으로 화면구출, 재 드로잉(다시그리기), 화면파기 순으로 이뤄진다. 각 사이클에서 호출되어지는 훅 메소드를 알아보겠다.
화면구축
createState()
● statefulWidget을 구축하자마자 호출된다.
● 위젯트리에 상태를 만들기 위해 호출된다.
class Home extends StatefulWidget{ @override HomeState<StatefulWidget> createState() => Home(); }
initState()
● 위젯 트리 초기화를 한다.
● 단 한 번만 호출된다. 또한 반드시 super.initState()를 호출해야 한다.
initState에서 실행되면 좋은 것들
1. 생성된 위젯 인스턴스의 BuildContext에 의존적인 것들의 데이터 초기화
2. 동일 위젯트리내에 부모위젯에 의존하는 속성 초기화
3. stream구독, 알림변경, 또는 위젯의 데이터를 변경할 수 있는 다른 객체 핸들링
@override void initState(){ super.initState(); }
didChangeDependencies()
● State객체의 종속성이 변경될 때 호출된다.
● initState뒤에 호출되지만 그 이외에도 호출된다.
@override void didChangDependencies(){ }
재 드로잉
build()
● 위젯으로 만든 UI를 구축한다.
● 다양한 곳에서 반복적으로 호출된다.
● 변경된 부분 트리를 감지하고 대체한다.
@override widget build(BuildContext context){ // add your widget }
didUpdateWidget()
● 위젯의 구성이 변경될 때마다 호출된다.
● 부모위젯이 변경되고 다시 그려져야 할 때 호출된다.
● oldWidget 인수를 취득해 비교한다.
● tip: 이 메서드는 기본적으로 위젯의 상태와 관련된 위젯을 재구성해야 하는 경우 initState()을 대치한다.
@override void didUpdateWidget(Home oldWidget){ super.didUpdateWidget(oldWidget); }
setStat()
● 상태가 변경되었을 때 프레임워크에 상태가 변경됨을 알리는데 사용되며 build context의 위젯을 다시 빌드하게 된다.
setState(() { });
화면파기
deactivate()
● state오브젝트가 트리로부터 삭제될 때마다 호출된다.
dispose()
● 객체가 트리에서 완전히 삭제되고 두 번 다시 빌드되지 않으면 호출된다.
@override void dispose(){ super.dispose(); }
함수테스트
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({super.key}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { @override void initState() { super.initState(); print('initState'); } @override Widget build(BuildContext context) { print('build'); return MaterialApp( home: Scaffold( body: Center( child: ElevatedButton( onPressed: () { setState(() { print('setState'); }); }, child: Text('button'), ), ), ), ); } }
맞는 테스트인지는 모르겠지만 이렇게 해봤을 때 UI에는 아래처럼 나타난다.
그리고 처음 터미널에는 아래처럼 print가 출력된다.
그리고 버튼을 두번 누르면
위에처럼 터미널에 나타난다.
initState함수가 다시 실행 안되는 이유는 initState는 해당 위젯의 위젯 트리에 삽입되어질 때, 1번 호출되는 메서드이다. 따라서 해당 위젯의 설정이나 트리 내 위치 정보인 BuildContext에 따라 결정되어지는 초기화를 할 때 사용한다.
[참고]
https://fronquarry.tistory.com/16
https://terry1213.github.io/flutter/flutter-statefulwidget-setState/