본문 바로가기

# 02/Flutter

[Flutter] StatefulWidget 의 State

반응형

플러터에서 위젯은 불변이므로 StatelessWidget 이든 StatefulWidget 이든 화면을 다시 빌드하면 이전 객체를 다시 이용하는 것이 아니라 새로운 객체가 생성된다.

 

StatelessWidget 은 상태를 관리하지 않으므로 보통은 데이터가 많거나 로직이 복잡하지 않는다. 따라서 상위 위젯으로 인해 화면이 다시 빌드될 때 객체가 새로 생성 되더라도 문제가 없다.

 

StatefulWidget 은 보다 많은 데이터에 복잡한 로직을 가진다. 이런 객체를 다시 빌드될 때마다 다시 생성한다면 비효율적이다.

따라서 StatefulWidget은 위젯 트리 구조에 포함해 매번 생성되게 만들고, 실제 데이터와 업무 로직은 State 객체를 따로 두어 화면이 다시 빌드될 때마다 매번 생성되지 않게 한다.

 

StatefulWidget 이 처음 생성될 때 State 객체도 함께 생성되지만 화면이 다시 빌드되어 StatefulWidget이 다시 생성되더라도 State 객체는 다시 생성되지 않고 이전에 사용하던 State 객체를 그대로 이용한다.

createState() 함수가 바로 State 객체를 반환하는 함수 인데 StatefultWidget이 처음 생성되는 순간에만 호출된다.

 

즉, 화면이 다시 빌드될 때마다 호출되지 않는다.

State 객체는 우선 타입을 기준으로 찾고 타입이 같은 객체가 여러 개이면 위젯의 키값으로 찾는다.

그래도 없으면 createState() 함수를 호출해 State 객체를 생성한다.

 

여기서 중요한 것은 결국 StatefulWidget은 State 객체를 따로 두고 메모리에 유지하면서 재사용하고, 화면이 다시 빌드될 때마다 StatefulWidget 객체만 생성된다는 점이다.

이런 이유로 StatefulWidget은 State 와 함께 사용한다.

 

 

 

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    print('---build _MyHomePageState');
    return Scaffold(
      backgroundColor: Colors.blue,
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          FirstStatelessWidget(),
          SecondStatefulWidget(),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
          });
        },
        child: const Icon(Icons.reset_tv),
      ),
    );
  }
}

class FirstStatelessWidget extends StatelessWidget {
  FirstStatelessWidget({Key? key}) : super(key: key) {
    print('---create FirstStatelessWidget');
  }

  @override
  Widget build(BuildContext context) {
    print('---build FirstStatelessWidget');
    return Container(
      width: 200,
      height: 200,
      color: Colors.green,
    );
  }
}

class SecondStatefulWidget extends StatefulWidget {
  SecondStatefulWidget({Key? key}) : super(key: key) {
    print('---create SecondStatefulWidget');
  }

  @override
  State<SecondStatefulWidget> createState() {
    print('---createState _SecondStatefulWidgetState');
    return _SecondStatefulWidgetState();
  }
}

class _SecondStatefulWidgetState extends State<SecondStatefulWidget> {

  @override
  Widget build(BuildContext context) {
    print('---build _SecondStatefulWidgetState');

    return Container(
      width: 200,
      height: 200,
      color: Colors.amber,
    );
  }
}

 

처음에 앱이 실행 될 때,

 

I/flutter (10404): ---build _MyHomePageState
I/flutter (10404): ---create FirstStatelessWidget
I/flutter (10404): ---create SecondStatefulWidget
I/flutter (10404): ---build FirstStatelessWidget
I/flutter (10404): ---createState _SecondStatefulWidgetState
I/flutter (10404): ---build _SecondStatefulWidgetState

 

 

플로팅 버튼을 눌러 _MyHomePageState 상태를 갱신 하여 화면을 다시 그리면

 

I/flutter (10404): ---build _MyHomePageState
I/flutter (10404): ---create FirstStatelessWidget
I/flutter (10404): ---create SecondStatefulWidget
I/flutter (10404): ---build FirstStatelessWidget
I/flutter (10404): ---build _SecondStatefulWidgetState

 

하위 위젯인 StatelessWidget, StatefulWidget 은 다시 생성되지만 createState() 메서드는 호출하지 않는다.

 

 

 

 

 

 

 

 


http://www.yes24.com/Product/Goods/117206541

 

Do it! 깡샘의 플러터 & 다트 프로그래밍 - YES24

‘깡샘’으로 유명한 앱 개발 전문가의 명성 그대로!다트 핵심 문법을 익히고 플러터로 모바일 앱을 만들어 보자!매년 수백 명의 개발자를 양성하는 IT 전문 강사이자 안드로이드 베스트셀러의

www.yes24.com

 

반응형