본문 바로가기
개발(Development)/Flutter

상태관리 시리즈 1 - Stateless와 Stateful 완전 정복

by GeekCode 2025. 8. 5.
반응형

Flutter 상태관리 시리즈 시작 – State 완전 정복

Flutter 앱을 만들다 보면, 버튼 하나 눌렀을 뿐인데 화면이 바뀌고,

 

입력값에 따라 UI가 달라지는 걸 자주 경험하게 돼요.

 

이처럼 눈에 보이는 모든 변화 뒤에는 '상태(State)'가 있답니다.

 

이번 시리즈에서는 Flutter에서 상태를 어떻게 다뤄야 하는지,

 

가장 기초적인 StatelessWidget, StatefulWidget부터


실제 앱에서 자주 쓰이는 Provider, Riverpod, Bloc까지


단계적으로 하나씩 차근차근 정리해볼게요.

Flutter 상태관리 기본 구조 이해 – Stateless와 Stateful

 

 

Flutter에서 앱 UI는 상태(state) 에 따라 변해요.


그리고 이 상태를 어떻게 관리하느냐에 따라

 

앱의 구조와 유지보수성이 크게 달라지죠.

 

그 첫 번째 글인 이번 편에서는


Flutter 상태관리의 출발점인

 

setState()의 개념과 구조를 살펴보면서


StatelessWidget vs StatefulWidget의 차이를

 

함께 알아보려고 해요.

 

 

 

 

 

 


Stateless vs Stateful

Flutter의 위젯은 크게 두 가지로 나뉘어요.

구분 설명
StatelessWidget 상태 없이 렌더링만 하는 위젯이에요. 외부에서 받은 값만을 기반으로 UI를 그려요
StatefulWidget 자체적인 상태(state)를 가질 수 있으며, setState를 통해 UI를 다시 그릴 수 있어요

 

 

 

 

StatelessWidget – 상태가 없는 위젯

class HelloText extends StatelessWidget {
  final String name;

  const HelloText({super.key, required this.name});

  @override
  Widget build(BuildContext context) {
    return Text('Hello, $name!');
  }
}

 

이런 위젯은 상태를 가질 수 없고,

 

name이 바뀌면

새로운 인스턴스를 만들어서

주입해줘야 해요.

 

 

 

 

 

StatefulWidget – 상태를 가질 수 있는 위젯

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

  @override
  State<MyCounter> createState() => _MyCounterState();
}

class _MyCounterState extends State<MyCounter> {
  int _count = 0;

  void _increment() {
    setState(() {
      _count++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('카운트: $_count'),
        ElevatedButton(
          onPressed: _increment,
          child: Text('증가'),
        ),
      ],
    );
  }
}

 

이 구조에서는 버튼을 누를 때마다

 

_count 값이 증가하고,

 

build()가 다시 실행되어

 

UI가 다시 그려져요.

 

 

 

 

 

 


상태란 무엇인가?

상태란 쉽게 말해

 

UI를 결정짓는 데이터예요.


예를 들어, 버튼을 눌렀는지 아닌지,

 

사용자가 입력한 텍스트,

 

서버에서 받은 응답 등

 

모두 상태에 해당하죠.

 

 

 

이 상태가 바뀌면,

Flutter는 위젯을 다시 그려서

화면에 변화를 반영해요.


바로 이 ‘상태 변화 → UI 갱신’ 구조가

 

Flutter 앱의 핵심이라고

 

할 수 있어요.

 

 

 

 


실무 적용 포인트

  • StatelessWidget은 고정된 UI나 반복되는 디자인 요소에 잘 어울려요.
  • 반면 StatefulWidget은 사용자 입력, 네트워크 응답처럼 변화가 많은 UI에 잘 맞아요.
  • setState()는 꼭 필요한 범위에서만 사용해야 빌드 성능을 지킬 수 있어요.
  • 관리해야 할 상태가 많아지면, ProviderBloc 같은 도구로 분리하는 걸 추천드려요.

 

 

 

 


생명주기 다이어그램

StatefulWidget은 다음과 같은 생명주기를 가지고 있어요.

 

 

StatefulWidget Lifecycle

  • initState(): 초기 설정 시 호출돼요
  • setState(): 상태 변경 시 UI를 다시 그려줘요
  • dispose(): 위젯이 제거될 때 호출돼요

이 생명주기에 대해서는 다음 시간에 자세히 다룰게요.

 

 

 

 


실습 과제 : 버튼을 눌러 배경색을 바꾸는 StatefulWidget 만들기

요구사항:

  • 화면 중앙에 ElevatedButton 하나를 배치한다.
  • 버튼을 누를 때마다 배경색이 빨강 → 파랑 → 다시 빨강으로 번갈아 바뀌어야 한다.
  • 색상 상태는 내부 상태로 관리하며, setState()를 활용해 갱신한다.

 

 

예상 결과:

  • 앱을 실행하면 초기 배경색은 빨강.
  • 버튼을 누르면 파랑으로 변경.
  • 한 번 더 누르면 다시 빨강.
  • 버튼을 계속 누를 때마다 번갈아 전환된다.

 

 

힌트:

bool isRed = true; 처럼 상태를 하나 두고

 

setState(() { isRed = !isRed; });로 토글하면 쉽게 구현할 수 있다.

 

 

배경색은 Container(color: isRed ? Colors.red : Colors.blue) 와 같이

 

조건부로 바꿔줄 수 있다.


다음 글 예고

이번 글에서는 StatelessWidgetStatefulWidget의 차이를 살펴봤어요.


다음 글에서는 상태 변화가 실제로 어떤 에 반영되는지를


StatefulWidget의 생명주기(Lifecycle) 관점에서 살펴볼 예정이에요.

 

  • 위젯이 생성될 때 어떤 메서드가 먼저 호출되는지
  • setState()는 정확히 언제 어떤 타이밍에 반영되는지
  • 그리고 위젯이 제거되기 직전에 어떤 처리를 해줘야 하는지

실제 UI 개발 시 궁금했던 부분들을 다이어그램과 함께 차근차근 정리해볼게요.

반응형