즉, 앱의 성능과 직접적인 관련이 있기 때문에 생명주기를 잘 관리해줘야 하는 것이다
플러터에서는 widget의 생성부터 파기까지 위젯의 생명주기가 관리 되어지고 있고, 생명주기의 특정 시점에서 특정 메소드가 호출되어진다.
이러한 life cycle 의 상태를 이해함으로써 widget의 정교한 제어가 가능하다.
Life cycle은 각 위젯이 얼만큼의 시간동안 동작하는지 이해하기에 좋은 개념이
다
createState()statefulWidget에 반드시 존재해야 한다statefulWidget을 구축하자마자 호출된다class ExampleWidget extends StatefulWidget {
const ExampleWidget({Key? key}) : super(key: key);
_ExampleWidgetState createState() => _ExampleWidgetState();
}
initState()build() 코드 전에 작성되어야 한다.// API 통신이나 부모요소에 의존하는 데이터일 경우
void initState() {
super.initState();
data = 'Initial data'; // data 초기화
// _counter = 0; 이 코드는 로컬변수이므로 아래처럼 사용하는 게 편리함
}
// local 변수를 사용하는 경우 : initState() 굳이 안 사용해도 됨
int _counter = 0;
didChangeDependencies()initState() 다음에 호출된다
void didChangeDependencies(){
super.didChangeDependencies();
/*state 변경 시 호출*/
}
build()build() 메서드는 버튼을 누르거나 액션을 할 경우마다 호출되기 때문에 자주 호출된다
Widget build(){
return Container(...)
}
didUpdateWidget()oldWidget
void didUpdateWidget(covariant T oldWidget) {
super.didUpdateWidget(oldWidget);
if(oldWidget.value != widget.value){
print('update!');
}
}
setState()build() 가 호출된다setState() 함수를 사용하지 않고 값을 변경시키는 경우, UI에 변경데이터가 반영되지 않는다void setState(() => {
_myState = value;
})
dispose()
void dispose() {
// ...
super.dispose()
}
class _AppState extends State<App> {
void initState() {
super.initState();
_counter = 0;
print('init!');
}
void dispose() {
super.dispose();
print('dispose!');
}
Widget build(BuildContext context) {
print("build!");
return MaterialApp(
...
각 메소드를 설정하고 print 해보면 콘솔창에 라이프사이클이 출력되므로 확인하기 용이하다
: 보여주기만 한다
위 사진 처럼 stateless 는 화면에 보여주기만 하는 build() 로 바로 넘어간다.
stateless 도 내부적으로 상태를 가진다
하지만 less를 사용하는 이유 ?
변경불가한 상태를 가지는 widget이기 때문이다
: 상태가 변하는 것까지 보여준다
statefulWidget은 상태라 변경가능한 widget이다
따라서 무수한 build() 가 쌓기면 시간이 오래 걸리며 성능이 떨어지게 되는 것이다
dispose() 를 통해 종료한다면, 순서에 맞게 Page3 부터 차례대로 종료될 것이다