-
Notifications
You must be signed in to change notification settings - Fork 0
Flutter Life Cycle
- Flutter의 모든 UI 요소들은 Widget 이다.
- StatelessWidget : Immutable State / StatefulWidget : Mutable State
Stateful에선 state object를 통해 build를 하게 된다.
- Stateful의 Constuctor가 제일 먼저 호출이 됩니다.
- 그다음 createState() : State를 생성
- initState() : State 초기화
- build() : Redering
- Stateful build()가 실행될때 Stateless 의 Constructor가 실행이 됩니다.
- 이어서 Stateless의 build()가 실행되어 화면에 무언가를 출력하게 됩니다.
- 이 후 사용자의 입력 및 이벤트가 발생하면, Stateful의 setState()가 호출로 State의 변화가 발생합니다.
- 그다음 4.5,6의 과정이 재 실행됩니다.
- 이때 Widget의 변경이 발생(소스변경같은 상황), 그래서 Stateful 의 didUpdateWidget()이 호출되고
- Statefule의 build()가 실행되고 다시 4,5,6번이 실행이 됩니다.
> 다음과 같은 단계를 포함하고 있다.
* createState()
* mounted == true
* initState()
* didChangeDependencies()
* build()
* didUpdateWidget()
* setState()
* deactivate()
* dispose()
* mounted == false
StatefulWidget을 빌드하도록 지시하면 즉시 [createState()]
가 호출된다. 이 메서드는 반드시 존재해야 한다.
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => new _MyHomePageState();
}
createState
가 state클래스를 생성하면 buildContext
는 state에 할당된다.
(BuildContext
는 위젯이 배치된 위젯 트리의 위치를 단순화 한 것이다.)
모든 위젯은 bool
형식의 this.mounted
속성을 가지고 있다. buildContext가 할당되면 true
를 리턴한다.
위젯이 unmounted
상태 일 경우, setState
를 호출하면 error
가 발생한다.
- tip: 이 속성은 state에
setState()
를 호출할때 유용하지만 해당 메서드가 언제, 얼마나 자주 호출 되는지는 명확하지 않다. 아마도 stream이 업데이트에 대한 응답으로 호출되는것 같다.setState()
호출전에 State가 존재함을if (mounted) {...
로 확인 할 수 있다.
위젯이 생성될때 생성자 진행 후, 처음으로 호출되는 메서드로 오직 한번만 호출된다. 또한 반드시 super.initState()
를 호출해야 한다.
이 함수의 @override
method를 사용할 때, best time은
- 생성된 위젯 인스턴스의 BuildContext에 의존적인 것들의 데이터 초기화
- 동일 위젯트리내에 부모위젯에 의존하는 속성 초기화
- Stream 구독, 알림변경, 또는 위젯의 데이터를 변경할 수 있는 다른 객체 핸들링.
@override
initState() {
// 부모의 initState호출
super.initState();
// 이 클래스에 리스너 추가
cartItemStream.listen((data) {
_updateWidget(data);
});
}
이 메서드는 위젯이 최초 생성될때 initState
다음에 바로 호출 된다.
또한 위젯이 데이터에 의존하는 객체가 호출될 때마다 호출된다. 예를 들면 업데이트되는 InheritedWidget
에 의존하는 경우.
build
는 항상 didChangeDependencies
호출 후에 실행되는 점을 명심해야 한다.
잘 사용하지 않지만 BuildContext.inheritFromWidgetOfExactType
을 호출하기 위해서 첫단계 시작점이다.
이건 데이터를 상속받는 위젯의 변경사항을 Listening
하게 만든다.
공식문서 또한 상속한 위젯이 업데이트 될때 네트워크 호출(또는 다른 비용이 큰 액션)(역자주: API호출)이 필요한 경우 유용하다고 함.
필수이며 재정의 대상(@override
)이고 반드시 Widget
을 리턴해야 한다.
이 메서드는 자주 호출된다(fps + render로 생각하세요).
플러터의 모든 gui는 Padding, Center 조차도 child 또는 children을 가진 위젯 이라는것을 기억하라.
didUpdateWidget()
는 부모 위젯이 변경되어 이 위젯을 재 구성해야 하는 경우, 함수가 호출되고(다른 데이터를 제공해야하기 때문에) 같은 runtimeType
과 함께 다시 만들어진다.
이것은 플러터가 state
를 재 사용하기 때문이다. 이 경우 initState()
에서 처럼 일부 데이터를 다시 초기화 해야 한다.
build()
메서드가 Stream 또는 other object와 같이 변경 가능한 데이터에 의존적인 경우 old object에서 구독을 취소하고 didUpdateWidget()
에서 새로운 인스턴스에 다시 구독 해야한다.
tip: 이 메서드는 기본적으로 위젯의 State와 관련된 위젯을 rebuild
해야 하는 경우, initState()을 대체한다.
@override
void didUpdateWidget(Widget oldWidget) {
if (oldWidget.importantProperty != widget.importantProperty) {
_init();
}
}
setState()
메서드는 플러터 프레임워크 자체적, 또는 개발자로 부터 자주 호출된다.
'데이터가 변경되었음’을 프레임워크에 알리는데 사용되며 build context
의 위젯을 다시 build
하게 한다.
setState()는 비동기화 할 수 없는 callback
을 받는다.(역자주: callback으로 비동기를 사용할 수 없다는 말임).
필요에 따라 자주 호출 할 수 있는 이유는 다시 그리는데(repainting) 소용되는 비용이 저렴하기 때문이다.
void updateProfile(String name) {
setState(() => this.name = name);
}
이 메서드는 거의 사용 되지 않는다.
deactivate()
는 tree
에서 State
를 제거할 때 호출 되지만, 현재 프레임 변경이 완료되기 전에 다시 삽입 될 수 있다.이 메서드는 State
객체가 tree
의 한 지점에서 다른 지점으로 이동 할 수 있기 때문에 기본적으로 존재한다.
영구적인 State Object
가 삭제될때 호출된다. 이 함수는 주로 Stream 이나 애니메이션 해제 시, 사용된다.
이 상태에서 state 객체는 결코 다시 mount되지 않으며, setState()가 호출되면 에러가 발생한다.
- https://flutterbyexample.com/stateful-widget-lifecycle/#6-didupdatewidget
- https://jaceshim.github.io/2019/01/28/flutter-study-stateful-widget-lifecycle/
- https://javaexpert.tistory.com/974