Dart/Flutter

[Flutter] StatelessWidget, StatefulWidget and Life Cycle

  • -
728x90

Flutter는 위젯으로 시작해서 위젯으로 끝난다. 화면에 표시된 모든 요소가 위젯이며, 눈에 보이지 않지만 화면을 구성하는 레이아웃도 위젯이다.

위젯은 크게 StatelessWidget과 StatefulWidget으로 분류할 수 있다.

 

StatelessWidget

말그대로 상태를 가지고 있지 않은 위젯이다. 어떠한 상태값도 가지고 있지 않기 때문에 StatelessWidget은 화면에서 특정 움직임이나 변화가 없이 정적이다.

화면에는 표시되지만, 사용자와 어떠한 인터렉션도 하지 않으며, 어떠한 움직이나 변화를 가지고 있지 않다.

 

StatefulWidget

StatelessWidet과는 반대로 어떠한 상태값을 가지고 있으며, 상태값에 의해 화면에 움직임이나 변화를 표현할 때 사용한다.

사용자의 인터렉션에 의해 모양이나 형태를 변경할 때 사용한다.

 

Widget tree

flutter는 기본적으로 위젯을 사용하여 개발한다. 한 위젯은 여러 위젯을 포함할 수 있으며, 모든 위젯은 부모-자식 광계를 가지게 된다. 이를 Tree 계층 구조로 표현하며 관리할 수 있다.

 

 

 

Life Cycle이란?

Foreground / Background 상태에 있을 때, 시스템이 발생시키는 event에 의해 App의 상태가 전환되는 일련의 과정을 말한다.

 

App States

 

  • Not running : 앱이 종료되거나 실행하고있지 않은 상태
  • Foreground : 앱이 실행되어 화면이 나타난 상태
  • Foreground Inactive : 상호작용이 불가능하지만 화면은 보이는 상태 (ex. 시스템 메시지)
  • Foreground Active : 상호작용이 가능하고 앱이 실행되고 있는 상태
  • Background Active : 백그라운드 상태에서 앱이 실행되고 있는 상태 (ex. 뮤직 앱)
  • Suspended : 빠르게 재실행하기 위해 메모리를 최소한 잡아놓은 상태

StatelessWidget 생명주기

Stateless

  • 위젯 생성 : build() 메서드가 최초 호출될 때 생성된다.
  • build() 메서드 호출 : build() 메서드는 Flutter Framework에서 UI를 그리기 위해 호출된다.
  • UI 그리기 : build() 메서드에서 정의한 UI가 화면에 그려진다.
  • 위젯 소멸

Stateless Widget은 자체적으로 상태를 가지고 잇지 않고, 부모 위젯으로부터 전달받은 값이 변경되면 rebuild 하여 새로운 위젯으로 대체 해버린다. 위젯의 변경이 일어나면 처음부터 Constructor와 build가 다시 실행되는 방식이다.

 

StatefulWidget 생명주기

우선 상태의 개념은 두 가지로 정의된다.

  1. 위젯에서 사용하는 데이터가 변경될 수 있다.
  2. 위젯이 빌드되면 데이터를 동기식으로 읽을 수 없다. 모든 상태는 build() 메서드가 호출될 때까지 설정되어야 한다.

StatefulWidget의 생명주기는 다음과 같이 정의된다.

  1. createState()
  2. mounted == true
  3. initState()
  4. didChangeDependencies()
  5. build()
  6. didUpdateWidget()
  7. setState()
  8. deactivate()
  9. dispose()
  10. mounted == false

 

1. createState()

createState() 메서드는 flutter가 StatefulWidget을 구성할때 즉시 호출되며 이 메서드는 필수로 존재해야한다.

 

2. mounted is true

createState()가 상태 클래스를 생성하면 buildContext가 해당 상태에 할당 된다.

모든 위젯에는 bool형태인 this.mounted 속성이 있는데, buildContext가 할당되면 true로 바뀐다.

 

위젯을 마운트 해제할 때 setState를 호출하는 것은 에러이다. 이 속성은 메소드가 상태를 호출하기 위해 setState()를 호출할 때 유용하지만, 얼마나 자주 해당 메서드를 호출할지는 확실하지 않다. 어쩌면 스트림 업데이트에 대한 응답으로 호출되었을 수도 있다. 이 때 if(mounted){...}을 사용하여 setState()를 호출하기 전에 상태가 존재하는지 확인할 수 있다.

 

3. initState()

State 객체가 생성되면 State객체의 생성자가 호출된다. 위젯이 최초 생성되는 상황이면 initState() 메서드가 호출되며, 한 번만 호출된다. 이 메서드에서 데이터나 속성값을 초기화 할 수 있다.

 

4. didChangeDependencies()

StatefulWidget이 생성될 때 호출되는 메서드로 initState() 다음에 바로 호출된다.

build() 메서드는 항상 didChangeDependencies() 메서드 다음에 호출된다.

부모 위젯이나, 자기 자신의 상태가 변경될 때는 호출되지 않지만, 해당 위젯이 참조하는 위젯이 변경되면 이 메서드가 호출된다.

 

5. build()

UI를 구현하는 부분으로 build() 메서드 안에 로직이 많으면 앱의 퍼포먼스가 낮아진다.

반드시 존재해야 하며 반드시 Widget을 반환해야 한다.

 

6. didUpdateWidget

부모 위젯에 의해 rebuild가 필요한 경우, build 메서드 호출 직전에 호출된다. 부모 위젯의 변경으로 인해 애니메이션을 다시 실행할 필요가 있는 경우에 자주 사용한다.

부모 위젯의 변경에 따라 상태값을 초기화할 필요가 있다면, 이 함수 안에서 setState를 통해 상태값을 다시 초기화 한다.

 

7. setState()

State 객체의 상태가 변경되었다는 것을 flutter에 알리는 용도이다. 그러면 flutter는 build() 메서드를 호출할 준비를 한다.

 

8. deactivate()

위젯 트리에서 상태를 제거하면 deactivate()가 호출되지만 현재 프레임 변경이 완료되기 전에 다시 삽입될 수 있다. 이 메서드는 기본적으로 상태 개체를 트리의 한 지점에서 다른 지점으로 이동할 수 있기 때문에 존재한다.

 

9. dispose()

State 객체가 제거될 때 호출되며, 영구적이다.

이 메서드는 모든 애니메이션, 스트림 등의 구독을 취소하는 방법이다.

 

10. mounted is false

이 상태 객체는 절대로 다시 마운트 될 없으며 오류가 발생하면 setState()가 호출된다.

 

 

 

https://flutterbyexample.com/lesson/stateful-widget-lifecycle

728x90
300x250
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.