Landroid

[플러터] Stateful 생명주기 본문

플러터

[플러터] Stateful 생명주기

silso 2020. 12. 17. 20:11

플러터를 알고 있다고 가정하고 생명주기에 대해 설명하겠습니다.

 

화면상 모든 것은 위젯

화면상에 표현되는 모든 것들을 위젯이라는 것은 아실 겁니다.

위젯은 StatelessWidgetStatefulWidget로 크게 나눌 수 있습니다.

이 두 가지에 따라 위젯들은 상태를 가질 수도 있고 가지지 않을 수 있습니다.

 

Stateless

의미만 봐선 상태가 없다는 뜻입니다. StatelessWidget은 상태를 가지지 않은 위젯이란 뜻입니다.

그럼 여기서 상태가 무엇일까요?

위젯에서 상태란 위젯에 대한 속성을 의미합니다. 예를 들어 Text 위젯에는 text가 상태겠네요.

text만 상태일까요? style, font, color 등 해당 위젯이 가지고 있는 속성을 모두 상태라고 부릅니다.

 

이렇게 위젯은 모두 상태를 가지고 있고 위젯은 위젯 트리에 관리되고 있습니다.

 

그럼 StatelessWidget은 상태를 안 가지나요? 아니요! StatelessWidget도 상태를 가집니다.

플러터에서 StatelessWidget은 한 번만 빌드하는 위젯을 의미합니다.

한마디로 위젯을 화면에 한 번만 그리고 다시 그리지 않는다는 뜻입니다.

 

그래서 StatelessWidget은 생명주기가 없고 관리하기 용이해서 상태가 변경되고 다시 화면을 그려야 하는 상황이 아니라면 StatelessWidget을 사용하길 권장합니다.

 

Stateful

그럼 StatelessWidget의 반대인 StatefulWidget은 상태가 변경되면 빌드를 여러 번 하는 위젯이겠죠.화면을 여러 번 그리기 때문에 StatelessWidget보다 관리하기 어렵고 성능도 조금 낮아질 수 있습니다.하지만 UI가 변경된 상태에 따라 업데이트가 되기 때문에 사용자에게 더 나은 경험을 선사해 주실 수 있습니다.

 

상태가 변경되면 바로 빌드되나요? 아니요! 아래 그림처럼 생명주기를 거친 다음에 build()에서 화면을 다시 그리게 됩니다.

 

생명주기

StatefulWidget 생명주기

1) StatefulWidget - Constructor

아시다시피 생성자입니다;; 생명주기에 포함되진 않고 그냥 클래스 생성 시 제일 먼저 호출됩니다.

 

2) CreateState

상태를 생성하는 콜백 함수입니다. State <T>를 상속받은 클래스를 아래처럼 생성합니다.

 

3) State - Constructor

상태 클래스의 생성자입니다. 1번과 헷갈릴 수 있으실 텐데 위젯과 상태는 별개입니다.

단지 위젯이 상태를 가지는 것 밖에 없습니다.

 

4) initState

상태가 생성되면 위젯도 같이 생성되는데 이때 호출됩니다. 처음 위젯이 생성되는 단 한 번만 호출됩니다.

 

5) didChangeDependencies()

위젯이 의존하는 위젯이 변경되면 호출됩니다.(ex: inheritedWidget)

위젯 트리에 대해 모르시다면 어려우실 텐데 간단하게 A위젯이 상속한 B위젯에서 업데이트되었을 때 호출됩니다.

 

6) build()

위젯의 상태가 변경되었을 때마다 화면에 위젯을 그립니다. didChangeDependenciesdidUpdateWidget로 빌드가 되지만 보통 setState 의해 자주 호출됩니다.

 

7) setState

상태가 변경되었다는 것을 알립니다.

 

8) didUpdateWidget

부모 위젯이 재 빌드되어 위젯이 갱신될 때 호출됩니다.

 

9) deactivate

위젯 트리에서 State 객체가 제거될 때마다 호출됩니다.

 

10) dispose

위젯 트리에서 State 객체가 영구적으로 제거될 때 호출된다.

상태도 제거되었으니 위젯도 같이 제거됩니다.

 

e1) Hot Reload

hot reload 하기 전 상태도 그대로 유지된 채 변경된 코드를 적용하기 때문에 앱이 살아있는 상태에서 빠른 실행이 가능합니다. 단, 빌드하는 것이 아닌 reassemble을 호출합니다. 

 

e2) reassemble()

hot reload를 실행할 때마다 호출됩니다. 이후 그림처럼 생명주기가 차례대로 진행됩니다.

 

 

아래는 예시용 코드입니다.

입맛대로 변경하셔서 생명주기를 한 번 확인해 보세요!

import 'dart:developer';

import 'package:flutter/material.dart';

class Test extends StatefulWidget {
  // @override
  // _TestState createState() => _TestState();
  
  @override
  State<StatefulWidget> createState() {
    log('createState');
    return _TestState();
  }
}

class _TestState extends State<Test> {
  @override
  void initState() {
    super.initState();
    log('initState');
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    log('didChangeDependencies');
  }

  @override
  void setState(fn) {
    super.setState(fn);
    log('setState');
  }

  @override
  void didUpdateWidget(covariant Test oldWidget) {
    super.didUpdateWidget(oldWidget);
    log('didUpdateWidget');
  }


  @override
  Widget build(BuildContext context) {
    log('build');
    return Container();
  }


  @override
  void deactivate() {
    super.deactivate();
    log('deactivate');
  }
  @override
  void dispose() {
    super.dispose();
    log('dispose');
  }

  @override
  void reassemble() {
    super.reassemble();
    log('reassemble');
  }
}

 

 

앞으로도 플러터와 관련된 포스팅이 자주 올라올 예정이니 자주 방문해주시면 감사합니다.

 

내용이 유익하셨다면 공감, 댓글 남겨주세요!

Comments