데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      Flutter 개발 시 StatefulWidget의 생명주기를 알아야하는 이유?

      매직 23.08.16
      9,894 10 0

      블로그 목적

      Flutter의 중요한 개념 중 하나인 StatefulWidget의 생명주기를 정리해본다.


      블로그 요약

      • Flutter의 StatefulWidget 생명주기를 알아본다.

      • Flutter의 StatefulWidget 생명주기를 알아야하는 이유에 대해서 개인적인 생각을 정리해본다.

      • Flutter의 StatefulWidget 생명주기 8단계에 대해서 간단한 예제 프로그램을 가지고 설명해본다.


      블로그 상세 내용

      안녕하세요, 이번엔 Flutter의 중요한 개념 중 하나인 StatefulWidget의 생명주기에 대해서 자세히 알아보겠습니다.

      Flutter 에서 StatefulWidget은 사용자 인터페이스의 동적인 부분을 관리하는 데 사용되며, 화면의 상태 변화를 처리하고 반영하는데 주로 활용됩니다.


      그런데 왜 위젯의 생명주기를 머릿속에 넣어둬야 할까요?

      위젯의 생명주기를 알아야 언제 데이터를 주고 받을지와 화면이 없어질때 어떤 로직을 처리해야 할지를 정리해서 넣을 수 있습니다.


      StatefulWidget은 Flutter에서 상태를 가진 위젯을 나타내는 클래스입니다.

      StatefulWidget의 생명주기를 이해하는 것은 애플리케이션 개발과 유지보수에 매우 중요합니다.

      아래는 StatefulWidget의 생명주기를 알아야 하는 이유에 대한 몇 가지 이유를 개인적으로 정리해보았습니다.

      1. UI 상태 관리: StatefulWidget은 상태를 가지는 위젯으로, 사용자 인터페이스의 상태를 관리하는 데 사용됩니다.

        위젯이 화면에 표시되고 변경될 때마다 생명주기 메서드가 호출되며, 이를 통해 화면의 상태를 업데이트하고 반응적인 UI를 구현할 수 있습니다.

      2. 상태 변경 감지: StatefulWidget의 생명주기 메서드를 이용하면 상태의 변화를 감지하고, 이에 따라 필요한 작업을 수행할 수 있습니다.

        예를 들어, 사용자의 입력에 따라 화면을 업데이트하거나 데이터를 로드하는 등의 작업을 수행할 수 있습니다.

      3. 자원 관리: 애플리케이션에서 사용되는 자원(메모리, 네트워크 등)을 효율적으로 관리하려면 StatefulWidget의 생명주기를 이해해야 합니다.

        필요한 자원을 적절하게 할당하고 해제하는 작업을 생명주기 메서드 내에서 수행할 수 있습니다.

      4. 문제 해결 및 디버깅: 애플리케이션에서 예기치 않은 동작이나 버그가 발생했을 때 StatefulWidget의 생명주기를 분석하면 문제의 원인을 찾아낼 수 있습니다.

        특정 생명주기 단계에서 발생하는 문제를 파악하여 수정할 수 있습니다.

      5. 성능 최적화: 상태 변화에 따른 화면 업데이트를 효율적으로 처리하여 성능을 최적화할 수 있습니다.

        예를 들어, 불필요한 업데이트를 방지하거나 비용이 큰 작업을 최소화할 수 있습니다.

      6. 동작 예측: StatefulWidget의 생명주기를 이해하면 위젯의 동작을 예측할 수 있습니다.

        화면이 언제 업데이트되는지, 어떤 순서로 메서드가 호출되는지 등을 알고 있으면 개발자가 의도한 동작을 보다 정확하게 제어할 수 있습니다.

      요약하자면, StatefulWidget의 생명주기를 알아야 하는 이유는 애플리케이션의 UI 상태 관리, 상태 변경 감지, 자원 관리, 문제 해결 및 디버깅, 성능 최적화, 동작 예측 등

      다양한 측면에서 개발과 유지보수의 품질을 높일 수 있기 때문입니다.


      그럼, StatefulWidget 위젯의 생명주기를 간단하게 요약해 볼까요?

      StatefulWidget 위젯의 생명주기는 아래와 같이 8가지로 구분할 수 있습니다.

      1. createState():

        StatefulWidget이 최초로 생성될 때, 먼저 createState() 메서드가 호출됩니다. 

        이 메서드는 StatefulWidget의 상태를 관리하는 State 객체를 생성합니다. 

        StatefulWidget은 상태가 변할 수 있는 요소이므로, 이 상태를 관리하는 State 클래스가 필요합니다.

      2. initState():

        createState() 메서드가 호출되고 나면, 이어서 initState() 메서드가 호출됩니다. 

        이 메서드는 State 객체가 초기화될 때 호출되며, 일회성 작업을 수행하는데 주로 사용됩니다.

        예를 들어, 초기 데이터 로드나 컨트롤러 초기화 등이 여기에 해당합니다.

      3. didChangeDependencies():

        만약 상위 위젯이나 InheritedWidget 등의 종속성이 변경되면, didChangeDependencies() 메서드가 호출됩니다. 

        이 메서드는 처음 위젯이 생성될 때보다 많이 호출되는데, 이전에 의존성이 변경되었을 때 실행됩니다. 

        데이터를 가져오거나 업데이트하는데 활용할 수 있습니다.

      4. build():

        위의 단계들이 완료되면, Flutter 프레임워크는 build() 메서드를 호출하여 화면을 그립니다. 

        이 메서드에서는 사용자 인터페이스의 모습을 반환하는 역할을 합니다. 

        build() 메서드는 매번 상태가 변경될 때마다 호출되며, 화면을 업데이트하는데 사용됩니다.

      5. didUpdateWidget():

        상위 위젯이 다시 렌더링되어 해당 StatefulWidget이 재구성될 때, didUpdateWidget() 메서드가 호출됩니다. 

        여기서는 새로운 위젯과 이전 위젯의 차이점을 처리하는 로직을 구현할 수 있습니다.

      6. setState():

        사용자가 상호작용하여 StatefulWidget의 상태가 변할 때, setState() 메서드를 호출하여 상태를 업데이트합니다. 

        이 메서드를 호출하면 Flutter는 해당 위젯을 다시 렌더링하고 화면을 업데이트합니다.

      7. deactivate():

        StatefulWidget이 더 이상 활성 상태가 아니게 되면, deactivate() 메서드가 호출됩니다. 

        이 메서드는 위젯이 화면에서 제거되기 전에 호출되며, 필요한 정리 작업을 수행하는데 사용됩니다.

      8. dispose():

        StatefulWidget이 파괴될 때, dispose() 메서드가 호출됩니다. 

        이 메서드는 State 객체의 정리 작업을 수행하는데 사용되며, 메모리 누수를 방지하고 리소스를 해제하는데 중요합니다.

      위에서 설명한 것처럼, StatefulWidget은 다양한 단계의 생명주기를 거쳐 화면을 업데이트하고 사용자의 상호작용을 처리합니다. 

      이러한 생명주기를 이해하고 정확히 활용할때 더 나은 앱으로 유저에게 깔끔한 서비스(?)를 제공할 수 있겠죠?


      그럼, 간단한 예시 프로그램을 작성해서 제가 설명했던 개념들을 한개씩한개씩 머릿속에 쉽게 넣을 수 있도록 해보죠?

      아래는 StatefulWidget 생명주기를 이해할 수 있도록 도움을 줄 수 있는 간단한 예시 프로그램 입니다.

      각 생명주기단계별로 print 함수로 로그를 찍어봤고요. (위에서 알아본 생명주기 대로 동작하고 있는지요?)


      프로그램을 간단하게 설명드리자면,

      최초 화면에 아래와 같이 저의 삶의 Block 6 리스트가 뿌려져(?) 있습니다. 

      "운동하기", "독서하기", "코딩하기", "데보션블로그쓰기", "유튜브영상올리기", "육아하기"

      그리고 FloatingButton 을 클릭하면 Block 6외에 "새로운 할일 0..1..2" 가 화면에 추가되는 프로그램입니다. 

      (우리가 인생을 산다는 것은 누구나 공평하게 주어지는 24시간의 삶에 자기 나름대로 얼마나 효율적인 방법으로 내가 사랑하는(?) 새로운 할일들을 추가할때?  삶이 변화할 수 있는거겠죠? )



      그럼 제가 왜 해당 프로그램을 구현하게 되었을까요?

      참고로 빌게이츠의 이야기인데요..

      어느날 부자가 된 비결을 묻는 기자의 질문에 빌게이츠는 아래와 같이 대답했다고 합니다. 

      나는 매일 스스로에게 2가지 말을 반복한다라고요...그것은 바로..

      하나 "왠지 오늘은 나에게 큰 행운이 생길것 같다" 이고 

      또 다른 하나는 " 나는 무엇이든 할 수 있다!" 라는 것이다 라고요...

      아직 저는 너무나 부족하지만, 이런맥락에서 해당 프로그램을 준비해 봤습니다. 

      프로그램처럼 저의 Block 6에 새로운 할일 0,1,2...가 제 삶에 지속적으로 추가되면서 이런 새로운 할일을 잘 감당하는 과정속에서

      큰 행운이 생기고, 새로운 할일을 경험할 때 나는 절대 못해가 아닌, "나는 무엇이든 할 수 있어!" 라고 생각하자고요......


      이런 마음으로 새로운 경험들을 체험하고 도전하면서 그곳에서 무엇을 남길 수 있을까? 라는 고민을 하면 정말로 나에게 소중한 삶의 경험으로 남더라고요...

      (그리고 그 경험을 토대로 저의 삶이 조금씩 변화하는것을 느낄 수 있었습니다. )


      얼마전에 저는 ICT 챌린지 2023 에 태풍을 뚫고(?) 작년에 이어서 멘토로 참여했는데요...

      원래 저의 계획으로는 그 시간은 강원도로 휴가를 가있는 시간이었습니다.

      하지만 태풍이 와서 저의 휴가계획은 미뤄지게 되었고요...

      (이런말이 있죠? 계획은 사람이 세우나, 이루는 것은 하늘이라고요....)

      아무튼, 원래 제가 계획했던 방향과는 다르게  ICT 챌린지 2023에 참여하게 되었죠..


      행사에 참여하며, 데보션에서 정성스럽게 챙겨주신 쉑쉑버거와 함께 멘티와 기획서를 두고 이야기하는 가운데 새로운 인사이트를 저 역시 가지게 되었고요..

      (와 이런 생각도 할수 있겠구나? 라고요)

      비록 비오는 날 집에서 T타워까지 오가는 것이 어떤관점에서는 귀찮을 수 있겠지만,

      그것을 감사하는 마음으로 이런 새로운 경험을 통해서 내 삶이 한단계 변화할 수 있는 선물이 그곳에 숨어있지 않을까? 라는 생각으로 다녀왔는데요..


      정말 잘한것 같습니다. ㅎㅎ 비록 멘토링 결과가 어떻게 되었든...

      저나름대로 온맘다해서 멘토링을 열심히 수행했고요...

      특히 주제가 저의 Block 6안에 있는 유튜브 관련 수익에 대한 부분이라서 더 열심히 했던것 같네요~~

      아무튼 저의 실무에서 산전수전 경험을 토대로한 조언이 멘티에게 조금이나마 도움이 되었기를 간절히 바래봅니다...


      아무튼, 삼천포로 빠졌던 ICT 챌린지 2023 멘토링 후기 이야기를 뒤로하고...(블로그를 이어나갈께요~ )

      import 'package:flutter/material.dart';
      
      void main() {
        runApp(TodoListApp());
      }
      
      class TodoListApp extends StatefulWidget {
        
        _TodoListAppState createState() {
          print('createState() 호출됨');
          return _TodoListAppState();
        }
      }
      
      class _TodoListAppState extends State<TodoListApp> {
        List<String> todos = ['운동하기', '독서하기', '코딩하기', '데보션블로그쓰기', '유튜브영상올리기', '육아하기'];
        int _count = 0;
      
        
        void initState() {
          super.initState();
          print('initState() 호출됨');
        }
      
        
        void didChangeDependencies() {
          super.didChangeDependencies();
          print('didChangeDependencies() 호출됨');
        }
      
        
        void didUpdateWidget(TodoListApp oldWidget) {
          super.didUpdateWidget(oldWidget);
          print('didUpdateWidget() 호출됨');
        }
      
        
        void deactivate() {
          print('deactivate() 호출됨');
          super.deactivate();
        }
      
        
        void dispose() {
          print('dispose() 호출됨');
          super.dispose();
        }
      
        void addTodo() {
          setState(() {
            print('setState() 호출됨, _count: $_count');
            todos.add('새로운 할 일: $_count');
            _count++;
          });
      }
      
        
        Widget build(BuildContext context) {
          print('build() 호출됨');
          return MaterialApp(
            home: Scaffold(
              appBar: AppBar(title: Text('할 일 목록')),
              body: ListView.builder(
                itemCount: todos.length,
                itemBuilder: (context, index) {
                  return ListTile(title: Text(todos[index]));
                },
              ),
              floatingActionButton: FloatingActionButton(
                onPressed: addTodo,
                child: Icon(Icons.add),
              ),
            ),
          );
        }
      }

      그럼 위의 프로그램을 토대로 위의 개념을 설명해 보도록 할께요~

      createState(): StatefulWidget을 생성하고, 상태를 관리하는 State 객체를 생성합니다.

      class TodoListApp extends StatefulWidget {
        
        _TodoListAppState createState() {
          print('createState() 호출됨');
          return _TodoListAppState();
        }
      }

      initState(): 앱이 시작될 때 초기 상태를 설정하거나 초기 데이터를 로드합니다.

      초기 데이터는 저의 Block 6 를 리스트로 넣어두었죠..

      class _TodoListAppState extends State<TodoListApp> {
        List<String> todos = ['운동하기', '독서하기', '코딩하기', '데보션블로그쓰기', '유튜브영상올리기', '육아하기'];
        int _count = 0;
        
        
        void initState() {
          super.initState();
          print('initState() 호출됨');
        }
        // ...
      }

      didChangeDependencies(): 종속성(의존성)이 변경될 때 호출되며, 여기서는 예를 들어 언어 설정 변경 시 데이터를 업데이트하는 작업을 수행할 수 있습니다.

        
        void didChangeDependencies() {
          super.didChangeDependencies();
          print('didChangeDependencies() 호출됨');
        }

      build(): UI를 렌더링하고 화면에 나타냅니다.

        
        Widget build(BuildContext context) {
          print('build() 호출됨');
          return MaterialApp(
            home: Scaffold(
              appBar: AppBar(title: Text('할 일 목록')),
              body: ListView.builder(
                itemCount: todos.length,
                itemBuilder: (context, index) {
                  return ListTile(title: Text(todos[index]));
                },
              ),
            ),
          );
        }

      setState(): 사용자의 상호작용으로 상태가 변경될 때 해당 상태를 업데이트하고 화면을 다시 그립니다.

      void addTodo() {
          setState(() {
            print('setState() 호출됨, _count: $_count');
            todos.add('새로운 할 일: $_count');
            _count++;
          });

      didUpdateWidget(): 위젯이 업데이트될 때 새로운 위젯과 이전 위젯의 차이점을 처리하는 로직을 구현할 수 있습니다.

        
        void didUpdateWidget(TodoListApp oldWidget) {
          super.didUpdateWidget(oldWidget);
          print('didUpdateWidget() 호출됨');
        }

      deactivate(): 다른 화면으로 이동할 때 호출되며, 필요한 정리 작업을 수행합니다.

        
        void deactivate() {
          print('deactivate() 호출됨');
          super.deactivate();
        }

      dispose(): 위젯이 파괴될 때 호출되며, 리소스 정리 등의 작업을 수행합니다.

        
        void dispose() {
          print('dispose() 호출됨');
          super.dispose();
        }

      위에서는 예시 프로그램을 토대로  StatefulWidget의 생명주기에 대해서 간단하게 설명해 보았고요.

      이제 앱을 실행하고 위젯의 생명주기와 상태 변화를 로그로 확인해 볼께요~

      아래는 최초 화면이고요..



      플로팅버튼을 세번 클릭하면 아래와 같이 새로운 할일 0,1,2 추가되는 간단한 프로그램입니다. (정말간단하죠? ㅎㅎ)


      로그는 아래와 같습니다. 아래와 같이 setState() 함수가 3번 호출되었죠?


      아무튼 Flutter의 위젯 생명주기 대한 간략한 설명을 마치겠습니다.

      다음에는 실제 프로젝트에서 이러한 개념을 적용하여 더 멋진 앱을 개발해보는 것이 저만의 목표입니다.


      오늘의 블로그는 여기까지고요

      항상 믿고 봐주셔서 감사합니다!


      그럼, 결론을 정리해보도록 하겠습니다.


      결론


      오늘은 Flutter의 중요한 개념 중 하나인 StatefulWidget의 생명주기에 대해서 간단하게 알아보았습니다. 

      아래와 같이 8가지 단계로 나누어져 있고요.. 아래 8가지는 꼭 머릿속에 넣어두시면 좋겠죠?


      1.createState(): StatefulWidget이 최초로 생성될 때, 먼저 createState() 메서드가 호출됩니다. 

      2.initState(): createState() 메서드가 호출되고 나면, 이어서 initState() 메서드가 호출됩니다. 

      3.didChangeDependencies(): 만약 상위 위젯이나 InheritedWidget 등의 종속성이 변경되면, didChangeDependencies() 메서드가 호출됩니다. 

      4.build(): 위의 단계들이 완료되면, Flutter 프레임워크는 build() 메서드를 호출하여 화면을 그립니다. 

      5.didUpdateWidget(): 상위 위젯이 다시 렌더링되어 해당 StatefulWidget이 재구성될 때, didUpdateWidget() 메서드가 호출됩니다. 

      6.setState(): 사용자가 상호작용하여 StatefulWidget의 상태가 변할 때, setState() 메서드를 호출하여 상태를 업데이트합니다. 이 메서드를 호출하면 Flutter는 해당 위젯을 다시 렌더링하고 화면을 업데이트합니다.

      7.deactivate(): StatefulWidget이 더 이상 활성 상태가 아니게 되면, deactivate() 메서드가 호출됩니다. 

      이 메서드는 위젯이 화면에서 제거되기 전에 호출되며, 필요한 정리 작업을 수행하는데 사용됩니다.

      8.dispose():StatefulWidget이 파괴될 때, dispose() 메서드가 호출됩니다. 

      이 메서드는 State 객체의 정리 작업을 수행하는데 사용되며, 메모리 누수를 방지하고 리소스를 해제하는데 중요합니다.


      물론 해당 프로그램에서는 didUpdateWidget(), deactivate(), dispose() 는 빠져있는데요..

      아직은 화면 이동을 다루지 않았으므로 호출되지 않았죠?


      앞으로 Flutter 에 대해서 공부하며, 블로깅을 하면서 생명 주기에 대해서 알아볼거니깐요...기대해 주세요~ㅎㅎ

      엇! 눈씻고 찾아봐도 didUpdateWidget(), deactivate(), dispose() 는 빠져있는데? 라고 생각하시지마시고요..

      언제 저 함수가 호출될까? 라는 궁금증으로 제 블로그를 시청해주세요~~^^;

      그리고, StatefulWidget의 생명주기를 알아야 하는 이유에 대해서도 간단하게 머릿속에 정리해두시길 추천드립니다.


      나의 목표 및 다짐을 항상 내곁에 두기

      • 목표

        • 나의 강점을 바탕으로 나의 일을 잘해냄으로써 타인과 사회를 아릅답게 만든다.

        • 현재 내가 가진 능력으로 누군가에 도움이 될 수 있을까? 에 대해서 항상 생각하기

        • 나는 블로그 생태계에서 IT 테크관련 파워블로거가 반드시 된다!

        • 유튜브 시장(?)을 호령하는 100만 유튜버가 반드시 된다!! (feat. 100만 유튜버가 반드시 될 매직!!)

        • 나는 꾸준히 공부하고 공부한것을 실천하는 창의적인 개발자가 된다.! (feat. devocean 개발&운영자가될 매직!!)

      • 목표를 이루기 위한 실천방안

        • 꾸준한 블로깅/기록법/독서법으로 넘버원이 아닌 온리원이 되보자.

        • 천사불여일행(千思不如一行)을 항상생각하며 체화 및 각인시키자.

          • "천번 생각하는것보다 한번 행동하는 것이 더 중요하다."

        • 기기일약 불능십보(騏驥一躍 不能十步) / 노마십가 공재불사(駑馬十駕 功在不舍)

          • 천리마도 한번에 열걸음을 뛸 수 없고, 느리고 둔한말이라도 열흘이면 하룻길을 간다.

        • 모든 실수에는 마술이 숨어 있다. 따라서 나는 실수하면 실수할수록, 그런 실수에서 더 많이 배울수록 삶에서 더 많은 마술을 갖는다.


      Advertising ...

      조금이나마 제 글이 도움이 되셨다면, 아래 배너 링크를 통해서 네이버인플루언서 팬이되주시면 제가 컨텐츠를 생산(?)하는데 큰 도움이 될것 같습니다. ^^;


      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      매직 님의 최신 블로그

      더보기
      동영상 기고하기