StatelessWidget 클래스 vs. StatefulWidget

여갱·2023년 7월 9일
0

Flutter

목록 보기
4/4

기본적으로 flutter 프로젝트를 시작하면 생성되는 main.dart 파일을 기준으로 stateless와 stateful widget을 비교해볼 것이다.

코드를 보면 크게 5개의 코드 덩어리로 분류할 수 있다.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget{..생략..}

class MyHomePage extends StatefulWidget{..생략..}

class _MyHomePageState extends State<MyHomePage>{..생략..}

차례대로 각각의 코드 덩어리가 의미하는 부분을 알아보자.

import 부분

  • flutter는 화면을 그리는 모든 디자인 요소를 위젯이라고 한다. package:flutter/material.dart 패키지에는 머티리얼 디자인 위젯들이 포함되어있다. 머티리얼 디자인을 기본으로 하는 앱이 되는 것이다.

main()함수

  • main() 함수는 앱의 시작점이다. 여기서는 runApp() 함수에 MyApp()인스턴스를 전달한다.

이제 진짜 나머지 3개의 코드 덩어리로 statelessWidget과 statefullWidget에 대해 알아보자.
참고로 미리 말하자면,
class MyApp extends StatelessWidget{..생략..} -> stateless
class MyHomePage extends StatefulWidget{..생략..} -> stateful
class _MyHomePageState extends State<MyHomePage>{..생략..} -> stateful이다.

그리고 vscode에서 stl까지 치면 stateless를 상속받는 class 틀이 딱 나옴!
stateful은 stf

1. StatelessWidget 클래스

StatelessWidget 클래스는 상태가 없고, 상태를 가지지 않는 위젯을 구성하는 기본 클래스다. 여기서 상태를 가지지 않는다는 것은 한 번 그려진 후 다시 그리지 않는 경우이며, 이러한 클래스는 프로퍼티(property)로 변수를 가지지 않는다.(상수는 가짐)

runApp()함수에 전달된 MyApp 클래스는 다음과 같이 정의되어있다.

class MyApp extends StatelessWidget{
	@override
    Widget build(BuildContext context){
    	return MaterialApp(..생략..);
   }    
}
  • MyApp 클래스는 StatelessWidget 클래스의 서브클래스다.(=상속받았다)
  • StatelessWidget 클래스는 build() 메소드를 가지고 있다.
    build 메소드는 위젯을 생성할 때 호출되는데, 실제로 화면에 그릴 위젯을 작성해 반환한다.

따라서
class MyApp extends StatelessWidget{
-> statelessWidget 클래스를 상속받은 MyApp 클래스는
return MaterialApp(..생략..);
MaterialApp 클래스의 인스턴스를 작성해 반환한다.


그럼 MyApp 클래스가 반환하는 MaterialApp클래스는 뭘까?

MaterialApp 클래스

build() 메소드가 반환하는 MaterialApp 클래스는 다음과 같다.

return MaterialApp(
	title: 'flutter',
    theme: ThemeData(
    	primarySwatch: Colors.blue,
    ),
    home: MyHomePage(title: 'flutterdd'),
);

이 코드에서는 title, theme, home 세 가지 이름있는 인수를 설정한다. 이 프로퍼티들을 설정하여 위젯의 속성을 표현한다.
title : 제목
theme : 테마. 코드에서는 파랑계열의 색상 테마로 설정함.
home : home에 작성하는 위젯이 실제 이 앱이 표시하는 위젯이 됨.

dart 언어에는 이름있는인수이름없는인수(일반 인수)가 있다. 위젯에 따라 각각 사용 방법이 다르다.

  • 이름 있는 인수는 인수 앞에 인수명을 쓴다.
    ex. MyHomePage(title: 'hello')
  • 이름 없는 인수명 안 쓴다.
    ex. Text('hello')

플러터에서 이름있는인수는 클래스의 프로퍼티에 값을 할당하는 것이며, 그 모양새는 클래스의 속성을 의미한다.

2. StatefulWidget 클래스

상태가 있는 위젯을 정의할 때는 StatefulWidget 클래스를 사용한다. main.dart 코드에서 StatefulWidget 클래스는

  • StatefulWidget을 상속받은 MyHomePage 클래스와
  • State<MyHomePage> 클래스를 상속받은 _MyHomPageState 클래스로 구성된다.

각각의 클래스 안에 작성된 코드를 자세히 들여다보자.

class MyHomePage extends StatefulWidget{
  MyHomePage({Key key, this.title}) : super(key: key); //-> MyHomePage 클래스의 생성자는 key와 title 프로퍼티를 
  // 옵션으로 받아서 super 키워드로 부모 클래스의 생성자에 key를 전달한다.
  final String title;
  
  @override
  _MyHomePageState createState() => _MyHomePageState();  
}

class _MyHomePage extends State<MyHomePage>{
  int _counter = 0;
  
  ...생략...
  
  @override
  _MyHomePageState createState(
 	int _counter = 0;
    
    ...생략...
    
    @override
    Widget build(BuildContext context){//_MyHomePageState 클래스의 상태에 따라
    //화면에 그려질 코드를 여기에 작성한다. 
      return Scaffold(...생략...);
    }
}

@override
_MyHomePageState createState() => _MyHomePageState(); -> MyHomePage 클래스에는 상속받은 createState()메소드를 재정의하여 _MyHomePageState 클래스의 인스턴스를 반환한다.

텍스트
class _MyHomePage extends State<MyHomePage>{} -> 상태 클래스

  • 상태 클래스 : State 클래스를 상속받은 클래스를 상태 클래스라고 부른다. 변경 가능한 상태를 프로퍼티 변수로 표현한다. 나중에 이 변수의 값을 변경하면서 화면을 다시 그리게 된다.

위젯에서 위젯으로 값 전달 과정

MaterialApp 클래스에서 home 프로퍼티에 MyHomePage 인스턴스를 생성하고 인수로 전달하며, 그와 동시에 MyHomePage의 title 인숫값으로 'flutterdd'를 전달했다.

return MaterialApp(
	title: 'flutter',
    theme: ThemeData(
    	primarySwatch: Colors.blue,
    ),
    home: MyHomePage(title: 'flutterdd'),
);

이렇게 전달 받은 title 인숫값은 MyHomePage 클래스의 생성자의 this.title 매개변수로 전달되어 필드 상수인 String title에 대입된다.

class MyHomePage extends StatefulWidget{//생성자
  MyHomePage({Key key, this.title}) : super(key: key); //-> MyHomePage 클래스의 생성자는 key와 title 프로퍼티를 
  // 옵션으로 받아서 super 키워드로 부모 클래스의 생성자에 key를 전달한다.
  final String title;
  
  @override
  _MyHomePageState createState() => _MyHomePageState();  
}

class _MyHomePage extends State<MyHomePage>{
    @override
    Widget build(BuildContext context){//_MyHomePageState 클래스의 상태에 따라
    //화면에 그려질 코드를 여기에 작성한다. 
      return Scaffold(
        appBar: Appbar(
          title: Text(widget.title), 
        ),
      );
    }
}

이렇게 위젯 사이의 데이터 전달은 생성자를 활용한다.
상태 클래스에서 StatefulWidget 클래스에 접근하려면 widget 프로퍼티를 사용한다.

그럼 이제 상태가 변화하는 statefulWidget의 상태가 어떻게 변경되는지 알아보자.

상태 변경

State 클래스에는 주로 상태를 저장할 변수들과 그 변수를 조작할 메서드를 작성한다.
main.dart 카운터 앱의 state 클래스를 보면 incrementCount()메소드로 setState() 메소를 실행시킨다.

setState() 메소드

  • 전달된 익명 함수를 실행한 후 화면을 다시 그리게 하는 역할이다.
  • 화면은 build()메소드가 실행되면서 그려지니까, setState()가 build()메소드가 다시 실행되게 하는 역할을 한다.
  • setState() 메소드는 State 클래스가 제공하는 메소드다.

[stateful, 동적인 화면이 되는 원리 정리]
MyHomePage 클래스는 StatefulWidget의 서브클래스이며 상태를 가질 수 있다. 그리고 그 상태는 State 클래스의 서브클래스로 정의한다. _counter 변수 값이 변경될 때마다 화면을 다시 그리면 동적인 화면을 가진 앱이 되는 거다.



진짜 정리

  • StatelessWidget 클래스는 상태가 없고, 상태를 가지지 않는 위젯을 구성하는 기본 클래스다.
  • StatefulWidget 클래스는 상태가 있는 위젯을 정의할 때 사용한다.
  • StatelessWidget 클래스는 build() 메소드를 가진다.
  • build 메소드는 위젯을 생성할 때 호출되는데, 실제로 화면에 그릴 위젯을 작성해 반환한다.
  • stateful에서 변경된 위젯을 그리고싶으면 State 클래스가 제공하는 setState()메소드를 이용해 build()메소드를 다시 실행하게 함.
  • 위젯 사이의 데이터 전달은 생성자를 활용한다.

0개의 댓글

관련 채용 정보