[플러터] 위젯의 생명주기

ho's·2022년 8월 11일
0

Do it 플러터 앱 프로그래밍 책 공부하기

책의 내용을 정리하면서 공부하기 위해, 글을 작성한다.


👜 위젯의 생명주기

  • 스테이트리스 위젯은 한 번 만들어지면 갱신할 수 없으므로 생명주기가 없다.
  • 즉, 다른 화면으로 넘어가면 모든 로직이 종료된다.
  1. 상태를 생성하는 createState()함수

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

class MyHomePage extends statefulWidget {
	
    _MyHomePageState createState() => new_MyHomePageState();
}

😶 Sate와 StatefulWidget 클래스를 왜 나누었나?

  • StatefulWidget보다 State클래스가 상대적으로 더 무겁기 때문에 StatefulWidget에서 감시하고 있다가 상태 변경 신호가 오면 State 클래스가 화면을 갱신하도록 구현한다.
  • 만약 StatefulWidget에서 바로 갱신하면 나중에 화면이 종료되어도 할당받은 메모리를 없앨 때 까지 오랜 시간이 걸릴 수 있다. 따라서 상태 변경 감시는 StatefulWidget 클래스가 담당하고, 실제 갱신 등은 State 클래스가 담당하도록 분리했다.
  1. 위젯을 화면에 장착하면 mounted == true

createState()함수가 호출되어 상태가 생성되면 곧바로 mounted 속성이 true로 변경된다.
mounted 속성이 true라는 것은 위젯을 제어할 수 있는 buildContext 클래스에 접근할 수 있다는 의미이다. 그렇지 않으면 오류가 발생한다.
buildContext가 활성화되어야 setState() 함수를 이용할 수 있다.

즉, setState() 함수를 호출하기 전에 mounted 속성을 점검 코드로 활용하면 안전하게 작성 가능하다.

if( mounted ) {
	setState()
}
  1. 위젯을 초기화하는 initState()함수

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


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

initState() 함수를 호출할때 내부에서 _getJsonData()함수를 호출해 서버에서 받아온 데이터를 화면에 출력하게 만들 수 있다.
만약 네트워크 통신이 안되거나 데이터가 이상하다면 화면에 표시하기 전에 미리 알아서 적절하게 대응해야 하므로 위젯을 초기화하는 imitState()함수에서 데이터를 준비해 놓는 게 좋다.

  1. 의존성이 변경되면 호출하는 didChangeDependencies()함수
    위젯을 초기화하는 initState() 함수가 호출된 후에 이어서 바로 호출되는 함수가 didChange Dependencies()입니다. 이 함수는 데이터에 의존하는 위젯이라면 화면에 표시하기 전에 꼭 호출해야 한다. 주로 상속받은 위젯을 사용할 때 피상속자가 변경되면 호출한다.

  2. 화면에 표시하는 build() 함수
    build() 함수는 Widget을 반환한다. 즉 위젯을 화면에 렌더링 한다. build() 함수에서 위젯을 만들고 반환하면 비로소 화면에 표시가 된다.


Widget build(BuildContext context){
	return MaterialApp(
    	title: 'Flutter Demo',
        theme: ThemeData(
        	primarySwatch: Colors.amber,
        ),
        home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
}
  1. 위젯을 갱신하는 didUpdateWidget() 함수

부모 위젯이나 데이터가 변경되어 위젯을 갱신해야 할 때 호출한다.
만약 initState()에서 특정 이벤트에 의해 위젯이 변경되면 didUpdateWidget() 함수를 호출해 갱신할 수 있다. initState() 함수는 위젯을 초기화 할 때 한 번만 호출 하므로 위젯이 변경되었을 때 호출하는 didUpdateWidget() 같은 함수가 필요합니다.


void didUpdateWidget(Widget oldWidget){
	if (oldWidget.importantProperty != widget.importantProperty){
    	_init();
    }
}
  1. 위젯의 상태를 갱신하는 setState()함수
    setState() 함수를 이용하면 데이터가 변경되었다는 것을 알려주고 변경된 데이터를 이용해 화면의 UI를 변경할 수 있도록 한다.
    플러터 앱을 만든다는 것은 곧 앱의 화면을 구성하는 일이므로 제일 많이 호출하는 함수이다.
void updateProfile(String name){
	setState(() => this.name = name);
}
  1. 위젯의 상태 관리를 중지하는 deactivate()함수

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

  1. 위젯의 상태관리를 완전히 끝내는 dispose()함수

State 객체를 영구적으로 끝낼때 사용한다. 이 함수를 호출한다는 것은 이제 해당 위젯을 종료한다는 뜻.

  • 네트워크 통신을 하거나 스트림 통신을 하다가 dispose() 함수를 호출하면 데이터 전송을 중지한다.
  • 위젯을 소멸할 때 꼭 호출해야하는 함수라면 dispose() 함수 안에서 호출해야 한다.
  • 만약 앞에서 살펴본 deactivate()함수 호출로 State 객체를 트리에서 제거한 후에 같은 State를 다시 다른 트리에 재사용할 경우 dispose()함수가 호출되지 않을 수 있다.
  1. 위젯을 화면에서 제거하면 mounted == false

State 객체가 소멸하면 마지막으로 mounted 속성이 false로 바뀌면서 생명주기가 끝난다.
mounted 속성이 false가 되었다는 것은 이 State는 재사용할 수 없다는 의미이다.

profile
그래야만 한다

0개의 댓글