플러터 Stateless widget 와 Stateful Widget #1

|

Stateless Widget과 Stateful Widget 을 알아보기 전에
먼저 플러터에 사용되는 State 와 Widget 에 대해 알아야 합니다.

State는 앱의 내부 데이터나 정보를 가질 수 있는 그릇입니다.
이를 활용해 앱의 사용자 인터페이스,텍스트, 이미지 등을 동작시킬 수 있어요.

즉 플러터에서 state 를 관리하려면 ‘StatefulWidget’ 을 사용하면 됩니다.

플러터 Stateless widget 과 Statefull Widget

Stateful Widget

동적이면서 값을 가진 위젯을 이야기합니다.

위젯이 동작하는 동안 데이터(Data) 변경이 필요한 경우 화면의 요소만 다시 그려서 변경된 부분을 위젯에 반영하는 동적인 위젯을 이야기합니다.

이 때 State 클래스는 build 메서드를 통해 화면을 업데이트한 뒤
setState 메서드를 호출하여 상태가 변경되었다는 것을 알려줍니다.

Stateless Widget

정적이면서 값을 가지지 않은 위젯을 이야기합니다.

화면이 로드될 때 한번만 그려지는 정적인 위젯입니다.
Stateless 는 앱의 상태가 없다는 뜻으로 해석할 수 있습니다.

이벤트 or 사용자 상호 작용에 의해 동작하지 않습니다.

  • 동적은 움직일 동이라는 뜻을 가지고 있으며 고정을 해야하는 경우는 정적이라는 단어를 사용합니다.
  • 동적 : Dynamic, 정적 : Static

두개의 위젯은 모두 불변이다

앞서 설명드린 위젯들의 속성은 모두 불변합니다.
그러면 Statefull 은 어떻게 변경작업을 하나요? 라는 질문에는
이미 존재하는 개체를 변경하는 것이며 상태가 변경될 때마다 위젯을 다시 빌드할 수 있게 됩니다. ( setState() )

StatelessWidget vs StatefulWidget 다이어그램

Stateless 위젯은 하나의 API 만 존재하지만
Statefulwidget 은 다시 빌드를 할 수 있도록 수많은 트리거를 가지고 있습니다. 상태를 변경할 때마다 didUpdateWidget() 위젯 구성이 호출됩니다.

예제

Stateless Widget 예제

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Stateless Widget 예제'),
        ),
        body: Center(
          child: MyStatelessWidget(),
        ),
      ),
    );
  }
}

class MyStatelessWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text(
      '안녕하세요, Stateless Widget 예제입니다.',
      style: TextStyle(fontSize: 20),
    );
  }
}

불변하면서 값을 변경할 수 없는 위젯입니다.

Stateful Widget

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Stateful Widget 예제'),
        ),
        body: Center(
          child: MyStatefulWidget(),
        ),
      ),
    );
  }
}

class MyStatefulWidget extends StatefulWidget {
  @override
  _MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text(
          '버튼을 누른 횟수:',
          style: TextStyle(fontSize: 20),
        ),
        Text(
          '$_counter',
          style: TextStyle(fontSize: 40),
        ),
        ElevatedButton(
          onPressed: _incrementCounter,
          child: Text('증가'),
        ),
      ],
    );
  }
}

불변하지만 변경이 가능한 위젯입니다.

참조

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다