DAMPER's blog

2-3. 위젯의 생명주기 본문

Flutter

2-3. 위젯의 생명주기

DAMPER 2022. 2. 17. 17:48
728x90

다음 내용은 'Doit! 플러터 앱 프로그래밍' 책 내용을 정리한 내용입니다.

 

 

위젯의 생명주기를 알면 언제 데이터를 주고받을지, 화면이 사라질 때 어떤 로직을 처리해야 할지를 정리해서 넣을 수 있다.

 

stateless widget는 한 번 만들어지면 갱신할 수 없으므로 생명주기가 없다.

즉, 다른 화면으로 넘어가면 모든 로직이 종료된다.

 

stateful widget은 10단계로 구분하는 생명주기가 있다.

 

 

1. 상태를 생성하는 createState() 함수

StatefullWidget 클래스를 상속받는 클래스는 반드시 createState() 함수를 호출해야 한다.이 함수는 다른 생명주기 함수들이 포함된 State 클래스를 반환한다. 즉, 위젯의 상태를 생성하는 함수이다.

class MyHomePage extends StatefulWidget {
	@override
    _MyHomePageState createState() => new _MyHomePageState();
}

 

StatefulWidget에서 감시하고 있다가 상태 변경 신호가 오면 State 클래스가 화면을 갱신하도록 구현한다.

 

 

 

2. 위젯을 화면에 장착하면 mounted == true

createState() 함수가 호출되어 상태가 생성되면 바로 mounted 속성이 true로 변경된다.mounted 속성이 true라는 것은 위젯을 제어할 수 있는 buildContext 클래스에 접근할 수 있다는 의미이다.buildContext가 활성화가 되어야 비로소 setState() 함수를 이용할 수 있다.buildContext가 활성화 되기 전에 setState()를 호출하면 오류가 발생한다. (화면 구성도 안 되었는데 setState() 함수로 위젯을 건드릴 수 없기 때문.)

if(mounted) {
	setState();
   }

위와같이 setState() 함수를 호출하기 전에 mounted 속성을 점검 코드로 활용하면 좀 더 안전한다.

 

 

 

3. 위젯을 초기화 ( initState() )

initState() 함수는 위젯을 초기화할 때 한 번만 호출한다.주로 데이터 목록을 만들거나 처음 필요한 데이터를 주고받을 때 호출한다.

@override
initState() {
	super.initState();
    _getJsonData();
}

initState() 함수를 호출할 때 내부에서 _getJsonData() 함수를 호출해 서버에서 받아온 데이터를 화면에 출력할 수 있다.

만약 네트워크 통신이 안되거나 데이터가 이상하면 화면에 표시하기 전에 미리 알아서 적절하게 대응해야 하므로 위젯을 초기화 하는 initState() 함수에서 데이터를 준비해 놓아야 한다.

 

 

 

4. 의존성이 변경됨 ( didChangeDependencies() )

initState() 호출 후 바로 호출되는 함수로 데이터에 의존하는 위젯일 때 화면에 표시하기 전에 꼭 호출해야한다.

주로 상속받은 위젯을 사용할 때 피상속자가 변경되면 호출한다.

 

 

 

5. 화면에 표시 ( build() )

build() 함수는 Widget을 반환한다. 즉 위젯을 화면에 렌더링한다.

build() 에서 위젯을 만들고 반환하면 비로소 화면에 표시된다.

 

 

 

6. 위젯을 갱신 ( didUpdateWidget() )

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

만약 initState() 에서 특정 이벤트에 의해 위젯이 변경되면 didUpdateWidget() 를 호출해 위젯을 갱신할 수 있다.

initState() 는 위젯을 초기화할 때 한 번만 호출하므로 위젯이 변경되었을 때 didUpdateWidget()이 호출된다.

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

 

 

7. 위젯의 상태를 갱신 ( setState() )

setState()를 이용해 데이터가 변경되었다는 것을 알려주고 변경된 데이터를 이용해 화면의 UI를 변경할 수 있다.

제일 많이 호출하는 함수 중 하나이다.

void updateProfile(String name) {
	setState(() => this.name = name);
}

 

 

 

8. 위젯의 상태 관리를 중지 ( deactivate() )

State 객체가 플러터의 구성 트리로부터 제거될 때 deactivate() 를 호출한다. 하지만 State 객체가 제거됐다고 해서 해당 메모리까지 지워지는 것은 아니다. deactivate()가 호출되더라도 dispose()를 호출하기 전까지는 State 객체를 재사용할 수 있다.

 

 

 

9. 위젯의 상태 관리를 끝내기 ( dispose() )

State 객체를 영구적으로 소멸할 때 dispose() 를 호출한다. 예를 들어 네트워크 통신을 하거나 스트림 통신을 하다가 dispose()를 호출하면 데이터 전송을 중지한다. 그리고 위젯을 소멸할 때 꼭 호출해야 하는 함수라면 dispose() 안에서 호출해야한다. 만약 deactivate() 로 State 객체를 트리에서 제거한 후에 같은 State를 다시 다른 트리에 재사용할 경우 dispose()가 호출되지 않을 수 있다.

 

 

 

10. 위젯을 화면에서 제거하면 mounted == false

State 객체가 소멸하면 마지막으로 mounted 속성이 false가 되면서 생명주기가 끝난다.

mounted 속성이 false가 되었다는 것은 이 State는 재사용할 수 없다는 의미이다. 그러므로 setState() 를 호출하면 오류가 발생한다.

 

호출 순서 생명 주기 내용
1 createState() 처음 stateful을 시작할 때 호출
2 mounted == true createState()가 호출되면 mounted는 true
3 initState() State에서 가장 먼저 실행, State 생성 후 한 번만 호출
4 didChangeDependencies() initState() 호출 후 호출
5 build() 위젯을 렌터링하는 함수. 위젯을 반환함
6 didUpdateWidget() 위젯을 변경해야 할 때 호출하는 함수
7 setState() 데이터가 변경되었음을 알림. 변경된 데이터를 UI에 적용하기 위해 필요
8 deactivate() State가 구성 트리로부터 제거될 때 호출
9 dispose() State가 완전히 제거되었을 때 호출
10 mounted == false 모든 프로세스가 종료된 후 mounted가 false로 됨.

 

 

 

728x90

'Flutter' 카테고리의 다른 글

3-1. material design  (1) 2022.02.19
2-2. Flutter 프로젝트 기본 구조 2  (0) 2022.02.14
2-1. Flutter 프로젝트 기본 구조  (0) 2022.02.12
1.4 Dart 스트림 통신하기  (0) 2022.02.12
1.3 Dart으로 JSON 데이터 주고받기  (0) 2022.02.11