위젯(Widget)이란?
- UI를 구성하는 기본 단위
- 사용자 인터페이스의 모든 요소는 위젯으로 표현된다.
- 종류
- Stateless Widget
- Stateful Widget
Stateless Widget
- 앱이 동작하면서 변하지 않는 위젯
- 가장 기본적인 위젯의 형태
- 기본 위젯들은 Stateless Widget인 경우가 많다.
- 처음 할당받은 모습대로 UI가 그려진다.
- 앱 생명주기동안 변경되지 않는다.
- 리빌드가 안 되는건 아니다.
- 위젯을 언제 트리에서 제거해야 할지, 언제 리빌드해야 할지는 외부로부터 결정된다.
Stateful Widget
- State라는 변경사항을 통해 생명주기를 갖는 위젯
- 동적으로 변하는 값에 따라 UI가 변경된다.
- State 객체의 setState 메소드를 실행하면,
위젯의 Flutter가 상태 변화를 인지하고 위젯을 다시 그린다.
Flutter의 Tree 구조
- 위젯 트리 (Widget Tree)
- 코드를 작성하여 화면에 그려지는 객체의 구조
- Flutter 앱의 사용자 인터페이스를 나타내는 위젯의 계층 구조
- 위젯 간의 부모-자식 관계 계층을 정의하여 동작한다.
- 불변성을 가진 객체들로 구성되어 있다.
- 생성 및 파기 비용이 매우 작도록 설계되어 있다.
- 엘리먼트 트리 (Element Tree)
- 퍼포먼스 최적화용
- build() 메소드가 실행되면 Flutter는 위젯 트리를 바탕으로 적절한 요소 객체를 생성하여
트리 구조로 메모리에 저장한다. - 어떤 UI가 화면에 렌더링될지 결정한다.
- 기변성을 가진 객체들로 구성되어 있다.
- 위젯 트리의 상태를 관리한다.
- 렌더 트리의 라이프사이클을 관리한다.
- 위젯 트리와 렌더 트리의 중재 역할을 한다.
- 렌더 트리 (Render Tree)
- 실제로 화면을 렌더링하는 트리
- 기변성을 가진 객체들로 구성되어 있다.
소스 코드 예시
위젯 트리 예시
flowchart TD
Scaffold --> SafeArea
SafeArea --> Row
Row --> D1("Text")
Row --> D2("Text")
Row --> D3("Text")
StatefulWidget의 생명주기
createState()
- State 객체를 생성한다.
mounted(true)
- State 객체를 생성하면, Flutter가 mounted라는 속성을 true로 설정한다.
- mounted 속성이 true라는 건 해당 State 객체가 BuildContext와 연결됬다는 걸 의미한다.
- mounted 속성은 해당 State 객체가 위젯 트리에 존재하는지의 여부를 판단하는 값으로 쓰인다.
- 생명 주기의 실제 단계로 표시되지는 않지만, 백그라운드에서 진행되는 작업이다.
initState()
- State 객체가 위젯 트리에 주입되면 Class 생성자 다음에 자동으로 실행되는 메소드
- State 객체가 처음 생성될 때 한 번만 호출된다.
- initState()에서는 BuildContext를 사용할 수 없다.
- 주 사용처
- 변수 초기화
- HTTP Request 관리
- Stream 구독
- 다른 객체의 핸들링
didChangeDependencies()
- initState() 다음에 호출되는 함수
- 부모 위젯이 변경되면 호출된다.
build()
- 위젯의 상태가 변경되었을 때마다 화면에 위젯을 그린다.
- 주로 setState에 의해 호출된다.
- didChangeDependencies나 didUpdateWidget에 의해 호출되기도 한다.
setState()
- 현재 위젯 내부의 상태가 dirty라는 것을 Flutter에 알려준다.
- UI에 영향을 줄 수도 있다는 것을 알리는 역할을 한다.
- 위젯의 상태가 변경되었다는 것을 알린다.
- setState() 호출 시 Flutter는 build() 메소드를 호출하여 위젯을 업데이트 후 재빌드한다.
위젯에서 무언가 값을 노출시키기 위한 데이터의 값이 변경되었을 때 호출한다.
setState()
는 개발자가 호출하는 유일한 메소드다.
didUpdateWidget()
- 부모 위젯이 재빌드되어 위젯이 갱신될 때 호출된다.
- Flutter는 didUpdateWidget() 이후에 build() method를 호출한다.
deactivate()
- 위젯 트리에서 위젯이 제거될 때 호출된다.
- State가 위젯 트리의 한 지점에서 다른 지점으로 이동할 때,
현재 프레임 변경이 완료되기 전에 다시 주입될 수 있다. - 거의 사용되지 않는다.
dispose()
- 위젯 트리에서 State 객체가 영구적으로 제거될 때 호출된다.
mounted(false)
- dispose()가 실행되고 나면 State 객체는 mounted 속성의 값은 false로 변경된다.
- mounted 속성의 값이 false가 되고 나면
State 객체는 다시 mount될 수 없고,
또한 setState() 호출 시 에러를 발생시킨다.
reassemble()
- hot reload를 실행할 때마다 호출된다.
- reassemble()이 실행되면 생명주기가 처음부터 다시 실행된다.