본문 바로가기
Flutter/Flutter Study

[Flutter] 위젯 상태관리 라이프사이클 / StatelessWidget, StatefulWidget LifeCycle 함수 메서드 정리

by 왁왁s 2023. 2. 8.

목차


     

     

    라이프사이클 (Life Cycle = 생명주기)란?

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

     

    쉽게 말하면 사용자가 앱을 실행하는 과정에 있어서, 컴포넌트가 생성되고, 사라지고, 종료되는 일련의 과정에서 갖게되는 상태(State)를 말한다.

     


     

    앱 상태 (App States)

    Not running : 앱이 종료되거나 실행을 하고 있지 않은 상태

    Foreground : 화면이 나타난 상태

    Foreground Inactive : 상호작용이 불가능하지만 화면은 보이는 상태 ex) 시스템 메시지

    Foreground Active :  상호작용이 가능하고, 앱이 실행되고 있는 상태

    Background Active : 백그라운드 상태에서 앱이 실행되고 있는 상태 ex) 멜론 뮤직 실행

    Suspended : 빠르게 재실행하기 위해 메모리를 최소한 잡아놓은 상태

     

     


     

     

    플러터 위젯의 생명주기 (Flutter Widget LifeCycle)

     

    플러터 위젯(Widget)의 특징

    • 플러터의 화면에 표시하는 모든 것이 위젯(Widget)이다.
    • 플러터 위젯(Widget)은 변경이 필요하면 기존의 위젯을 모두 없애고, 새로운 위젯으로 대체한다.

     


     

    Stateless Widget 라이프사이클(생명주기)

    Stateless 위젯은 단순히 화면을 구성하는 위젯이므로, Stateful 위젯의 비해 단순한 라이프사이클을 가진다

    •  한번 위젯을 생성하고 위젯의 구성요소에 대한 변화가 없을 때 사용하는 위젯이다.
    • Stateless Widget에서는 Constructor 생성 후 build() 함수를 호출해 UI를 구성한다.
    • Stateless Widget은 라이프 사이클동안 단 한번의 build() 함수를 실행한다.
    • Stateless Widget은 자체적으로 상태(State)를 가지고 있지 않고, 부모 위젯으로부터 전달받은 값이 변경이 되면 rebuild 해서 새로운 위젯으로 대체를 해버린다. 위젯의 변경이 일어나면 처음부터 Contructor와 build가 다시 실행되는 방식이다.

     

     

     


     

     

    Stateful Widget 라이프사이클(생명주기)

    • Stateful Widget은 Stateless와 달리 자체적으로 상태(State)를 가지고 있어 라이프사이클이 복잡하다.
    • initState()는 Stateful Widget이 생성될 때 '한번'만 호출되는 함수로 상태(State)를 초기화할 때 사용한다.
    • 상태를 관리하기 위해서는 build()를 여러 번 부를 수 있어야 하는데, 기존의 Stateless 방식으로는 상태를 관리할 수가 없다. 
      • 그렇기 때문에 Stateful Widget은 상태의 관리를 위해 기존의 위젯의 방식과, build를 여러 번 부를 수 있는 방식을 함께 사용해 2개의 클래스(Class) 형태로 구성한다.

    Stateful Widget LifeCycle 순서

    1. Stateless Widget에서는 Constructor 호출 후 build() 함수를 호출하여 UI 를 구성한다. 

    2. StatefulWidget은 Constructor에서 createState() 호출하고 상태(State)를 만든다.

    3. 이후에 initState() 를 호출해 초기화를 하고, didChangeDependencies() 가 불리고 변경이 필요한 상태인 dirty 상태가 된다. 

    4. build() 함수를 호출되고 화면에 UI가 나타나 clean 상태가 된다. 

    5. 만일 State를 변경하면 setState()에서 build()를 다시 호출하고 didUpdateWidget()의 return에 따라서 build() 실행 여부를 결정한다.

    6. didUpdateWidget() 함수를 사용해서 rendering여부를 결정할 수 있어, 성능 최적화를 진행하는 경우에는 didUpdateWidget() 함수를 @override 함수로 구현할 수 있다.

     

    출처 : https://flutter-lifecycle-widgets.medium.com/life-cycle-of-widgets-in-flutter-618b72a7f3f1)

     



    라이프사이클, 간략한 함수(function) 설명

     

    createState()

    • state object(객체)를 생성
    • 해당 객체는 해당 Widget에 대한 모든 변경 가능한 state가 유지되는 곳

     

    initState()

    • Stateful Widget이 생성될 때 '한번'만 호출되는 함수로 상태(State)를 초기화할 때 사용
    • 반드시 super.initState()를 호출

     

    didChangeDependencies()

    • initState()와 마찬가지로 Stateful Widget이 생성될 때 호출되는 함수로 initState() 다음에 바로 호출
    • build() 는 항상 didChangeDependencies() 다음에 호출
    • InheritedWidget이나 Provider를 사용하는 경우, InheritedWidget이나 Provider의 내용이 변경될 때마다 호출
    • 부모 위젯이나, 자기 자신의 상태가 변경될 때는 호출되지 않지만, 해당 위젯이 참조(Depedency)하는 위젯(InheritedWidget이나 Provider)이 변경되면 didChangeDependencies 함수가 호출

     

    build()

    • UI를 구현하는 부분으로 buiild 안에 로직이 많으면 앱의 퍼포먼스가 낮아진다.
    • 반드시 존재해야 하며 @override 재정의 대상이고, 반드시 Widget을 반환해야 한다.
    • UI위젯을 랜더링 할 때 마다 호출

    didUpdateWidget

    • 부모 위젯에 의해 rebuild가 필요한 경우, build 함수 호출 직전에 호출
    • 부모 위젯의 변경으로 인해 애니메이션을 다시 실행할 필요가 있는 경우에 자주 사용
    • 부모 위젯에 변경에 따라 상태값을 초기화할 필요가 있다면, 이 함수안에서 setState를 통해 상태값을 다시 초기화

    deactive

    • 상태(State) 객체가 트리에서 제거될 때 호출하는 함수

    dispose

    • 위젯 객체가 위젯 트리에서 영구적으로 제거될 때 호출
    • 상태 객체도 함께 제거되므로 deactivate 가 먼저 호출되어 상태 객체가 제거되었음을 알리고, 이후 dispose가 호출되어 위젯 객체가 삭제되었음을 알리는데 사용

     

     


     

    Stateful Widget 3가지 패턴(Pattern)

    1. 기본적인 StatefulWidget 생명주기

    기본적인 생명주기는 위젯이 생성되고 없어지는 단계이다.

    1. 모든 클래스와 마찬가지로 Constructor가 호출된다.
    2. Stateless와 달리 build()가 아닌 createState()를 호출해 상태(State)를 만든다
    3. 3~7번 위에 언급한 순서와 같음.
    4. 위젯을 삭제가 되는 경우에 deactivate-dispose를 불러 삭제가 된다.

     

     

    2. 파라미터가 바뀌었을 때 생명주기

    1. 파라미터가 바뀌면 Stateless Widget과 마찬가지로 위젯이 삭제된다.

    2. 새로 생긴 위젯이 새로 생겨 Constructor는 실행되지만 createState는 실행되지 않는다.
        기존에 삭제된 위젯의 State를 찾아서 그것을 그대로 사용해 재활용을 한다.

    3. State가 Clean인 상태에서 didUpdateWidget 함수가 실행되면 Constructor로 인해서 바뀐  값들을 기반으로 빌드를 다시 실행을 해야 한다.

    4. 그러면 다시 빌드를 하기 위해 dirty 상태로 바꾼다.

    5. 변경된 값들을 기반으로 build 함수를 다시 실행을 한다.

    6. Clean 상태로 돌아간다.   

     

     

    3. setState를 실행했을 때 생명주기

    • setState는 State가 제공해주는 함수이다. 이는 State가 clean한 상태일 떄 사용이 가능하다.
    • setState 함수는 State 안에서 직접 실행할 수 있다.
      • 지금까진 파라미터를 변경해 위젯의 상태를 변경할 때 외부에서 가져온 파라미터를 넣었다.
      • 그러나 setState는 State에서 내부에서 자체적으로 실행을 해서 build를 재실행한다. 이 때문에 Stateful Widget을 많이 사용한다.

    1. clean 상태에서 바꾸고 싶은 변수를 바꿔서  setState를 호출한다

    2. dirty 상태가 된다.

    3. 바뀐 값에 따라 build를 실행한다.

    4. 다시 clean 상태로 바뀐다.


     

     

     

    전반적인 Stateful 위젯 호출 순서

    Stateful 위젯이 생성될 때

    : Constructor > initState > didChangeDependencies > build

     

    setState가 호출되었을 때

    : build

     

    InheritedWidget 또는 Provider의 값이 변경되었을 때

    : didChangeDependencies > build

     

    부모 위젯으로부터 전달받는 값이 변경되었을 때

    : didUpdateWidget > build

     

    상태 객체가 제거되었을 때

    : deactivate > build

     

    위젯 객체가 제거될 때

    : deactivate > dispose

     

     


    Stateless Widget VS Stateful Widget 화면 비교

    댓글