플러터(Flutter) - 위젯의 생명주기 이해하기
본문 바로가기

앱/Flutter

플러터(Flutter) - 위젯의 생명주기 이해하기

728x90
반응형

안녕하세요 놀이방사장입니다.

 

이번 포스팅은 플러터

"위젯의 생명주기"에 대해 포스팅하겠습니다.

 

위젯의 생명주기를 알아야하는 이유


위젯의 생명주기를 알면 좋은 점은 언제 데이터를 주고 받을 지 , 화면이 사라질 때 어떤 로직을 처리할지 정할 수 있습니다.

EX)

특정화면에서 소리로 문서를 읽을 때 화면이 종료화면 소리가 그만나와야함 -> 계속 소리가 나오는 상황을 막을 수 있다.

이럴 때는 화면이 사라질 때 멈추는 기능(함수)을 넣어야한다.

 

스테이트풀 위젯의 생명주기(10단계)

스테이스리스 위젯은 한 번 만들어지면 갱신할 수 없기 때문에 생명주기가 없다.

-> 다른 화면으로 넘어가면 모든 로직이 종료된다.

 

1. 상태를 생성하는 createState함수

StatefulWidget클래스를 상속받는 클래스는 반드시 createState() 함수를 호출해야한다.

이 함수는 다른 생명주기 함수들이 포함된 State클래스를 반환한다.

-> 위젯의 상태를 생성하는 함수이다.

 

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

 

 

2. 위젯을 화면에 장착하면 mounted == true

createState() 함수가 호출되어 상태가 생성되면 mounted속성이 true로 변경된다.

mounted속성이 true라는 것은 위젯을 제어할 수 있는 buildContext 클래스에 접근할 수 있게 된다.

buildContext가 활성화되어야 setState()함수를 이용할 수 있다.

왜냐하면 화면구성이 되지 않았는데 setState()함수를 이용해 위젯을 움직일 수 없기 때문에 -> 오류가 떨어짐

 

그래서 setState()함수를 호출하기 전에 mounted 속성을 사용하면 좀 더 안전하게 코드를 작성할 수 있다.

if(mounted){
  setState()
}

 

 

3. 위젯을 초기화하는 initState()함수

initState() 함수는 위젯을 초기화할 때 한 번만 호출 된다.

주로 데이터 목록을 만들거나 처음 필요한 데이터를 주고 받을 때 사용

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

위에 코드를 보면 initState() 함수를 호출할 때 내부에서 _getJsonData() 함수를 호출해 서버에서 받아온 데이터를 화면에 뿌릴 수 있습니다.

만약 통신이 안되서 데이터가 조회되지 않는다면 화면에 표시하기 전에 알아서 적절하게 대응해야하므로 위젯을 초기화 하는 initState() 함수에 준비하는 게 좋다.

 

4. 의존성이 변경되면 호출하는 didChangeDependencies() 함수

위젯을 초기화하는 initState() 함수가 호출된 후에 이어서 바로 호출되는  함수가 didChangeDependencies()이다.

이 함수는 데이터에 의존하는 위젯이라면 화면에 표시하전에 호출해야한다.

주로 상수받은 위젯을 사용할 때 피상속자가 변경되면 호출한다.

 

5. 화면에 표시하는 build() 함수

build함수는 앞서 데모 앱에서도 재정의해서 사용해봤다

이 함수는 Widget을 반환한다.

즉 화면의 위젯을 랜더링한다.

build()함수에서 위젯을 만들고 반환하면 화면에 나오게 된다.

@override
Widget build(BuildContext context) {

  return MaterialApp(
    title: 'Flutter App',
    theme: ThemeData(
      primarySwatch: Colors.blue,
      visualDensity: VisualDensity.adaptivePlatformDensity,
    ),
    darkTheme: ThemeData.light(),
    home: Scaffold(
      body: Center(
        child: ElevatedButton(
          child: Text('$str'),
          style: ButtonStyle(
            backgroundColor: MaterialStateProperty.all(_color)
          ),
          onPressed: (){
            if(str == 'Click me'){
              setState(() {
                str = 'Hello';
                _color = Colors.pink;
              });
            }else{
              setState(() {
                str = 'Click me';
                _color = Colors.blueAccent;
              });
            }
          },
        ),
      ),
    ),
  );
}

 

 

 

이전 포스팅에서 짰던 build함수

 

6. 위젯을 갱신하는 didUpdateWidget() 함수

부모위젯이나 데이터가 변경되어 위젯을 갱신해야할 때 호출한다.

만약 initState() 에서 특정 이벤트에 의해 위젯이 변경되면 didUpdateWidget() 함수를 호출해 위젯을 갱신할 수 있다.

initState() 함수는 위젯을 초기화할 때 한 번만 호출되기에 위젯이 변경될 때 호출하는 didChageWidget 같은 함수가 필요하다.

@override
void didUpdateWidget(widget oldWidget){
  if(oldWidget.importantProperty ! = widget.importantProperty){
    _init();
  }
}

 

7. 위젯의 상태를 갱신하는 setState() 함수

setState() 함수를 이용하면 데이터가 변경되었다는 것을 알려주고 변경된 데이터를 이요해 화면의 UI를 변경시켜준다.

플러터앱을 만든다는 것은 앱의 화면을 구성하는 일이 제일 많으므로 가장 많이 쓰는 함수이다.

 

8. 위젯의 상태관리를 중지하는 deactivate() 함수

deactivate() 함수는 State() 객체가 플러터의 구성 트리로부터 제거될 때 호출된다.

하지만 State객체가 제거됐다고 해서 해당 메모리까지 지워지지는 않는다.

deactivate() 함수가 호출되더라도 바로 다음에 설명하는 dispose)(함수를 호출하기 전 까지는 State 객체를 재사용할 수 있다.

 

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

State 객체를 영구적으로 소멸할 때 호출한다.

이 함수를 호출한다는 것은 이제 해당 위젯을 종료한다는 뜻이다.

예를 들어 네트워크 통신이나 스트림통신을 할때 dispose()함수를 호출하면 데이터 전소을 중지합니다.

그래서 위젯을 소멸할 때 꼭 호출해야하는 함수이면 dispose() 함수안에서 호출해야한다.

 

10. 위젯을 화면에서 제거하면 mounted == false

State 객체가 소멸하면 마지막으로 mounted 속성이 false로 되면서 생명주기가 끝나게 된다.

mounted속성이 false가 되었다는 것은 이 State는 재사용할 수 없다는 의미이다.

 

그러므로 setState() 함수를 호출하면 오류가 뜬다.

 

총 정리

 

호출 순서 생명 주기 내용
1 createState() 처음 스테이트 풀이 시작할 때 호출됨
2 mounted == true createState() 함수가 호출되면 mounted는 true
3 initState() State에서 제일 먼저 실행되는 함수, State 생성 후 한 번만 호출
4 didChangeDependencies() initState() 호출 후 호출되는 함수
5 build() 위젯을 랜더링하는 함수, 위젯을 반환
6 didUpdateWidget() 위젯을 변경할 때 호출하는 함수
7 setState() 데이터가 변경되었음을 알리는 함수 변경된 데이터를 UI에 적용시키기 위해 필요
8 deactivate() State가 제거될 때 호출
9 dispose() State가 완전히 제거되었을 때 호출
10 mounted == false 모든 프로세서가 종료된 후 mounted 가 false가 된다.

 

반응형