1. StatefulWidget 과 StatelessWidget 의 의미
StatefulWidget과 StatelessWidget은 Flutter에서 위젯을 정의할 때 사용되는 두 가지 주요 클래스입니다. 이 두 위젯은 화면에 UI를 렌더링하지만, 상태(State)를 관리하는 방식에서 큰 차이가 있습니다.1. StatelessWidget
- 상태가 없는 위젯입니다.
- 변경되지 않는 데이터(immutable data)를 기반으로 UI를 렌더링합니다.
- 위젯이 빌드되고 난 후에 상태가 변경되지 않으므로, 한 번 그려지면 그 UI는 다시 변하지 않습니다.
- 데이터를 변경하거나 업데이트할 필요가 없고, 정적인 화면을 나타낼 때 주로 사용됩니다.
특징:
- 상태를 유지하지 않음: StatelessWidget은 내부적으로 상태를 저장하지 않으며, 렌더링할 때 주어진 데이터를 기반으로 UI를 그리기만 합니다.
- 재렌더링: 만약 UI가 변경되어야 한다면, 전체 위젯을 재생성해야 합니다.
2. StatefulWidget
- 상태를 유지할 수 있는 위젯입니다.
- 위젯이 빌드된 이후에도 상태(State)를 변경하고, 그에 따라 UI가 변경될 수 있습니다.
- 사용자 입력, 네트워크 요청 등으로 인해 데이터를 업데이트하고 싶을 때 StatefulWidget을 사용합니다.
- 상태는
State객체에 저장되며,setState()메서드를 호출하면 상태를 변경하고 UI를 다시 렌더링할 수 있습니다.
특징:
- 상태 관리: StatefulWidget은 동적인 UI를 구현할 때 사용됩니다.
State객체가 위젯의 상태를 저장하고, UI를 업데이트할 때는setState()메서드를 호출합니다.
- 라이프사이클: StatefulWidget은 자체 라이프사이클을 가지고 있습니다. 위젯이 생성되고, 초기화되며, 소멸될 때까지의 단계들을 처리할 수 있습니다. 대표적인 라이프사이클 메서드로
initState()와dispose()가 있습니다.
2. StatefulWidget 과 StatelessWidget 의 사용 방법

화면의 데이터를 통신으로 받아 재구성할 때 일부분만 변경함에도 불구하고 화면 전체를 새로 그리는 것은 상당히 비효율적인 방식이다.
Flutter 에서는 고정인 화면을 사용할 때
StatelessWidget 을 그리고 데이터를 통신 받아 화면이 바뀌는 부분은 StatefulWidget 방식을 사용한다.위의 그림을 예시로 설명하자면,
main 1번 ( 2번 )
class 2번 ( 3번, 4번, 5번 )
class 3번 ( 6번 )
class 4번 ( 7번 )
class 5번 ( 8번, 9번 )
왼쪽의 그림의 상황에서 2번에서 원하는 데이터를 불러오는 기능이 있다면 2번 하나를 위해 3번~9번까지 관련 없는 부분이더라도 상관없이 화면이 전체가 reloading 될 것이다.
반면에 오른쪽 그림처럼 데이터를 불러오는 기능을 최대한 바깥쪽으로 5번으로 포장하여 뺀다면 화면은 5, 8, 9 번만 reloading 될 것이다.
이처럼 화면을 부분 reloading 하는 기능을 가지고 있다면
StatefulWidget 을 하위 메서드로 구분지어 분리 시키는 것이 효율적이다.3. StatefulWidget 과 StatelessWidget 의 예시
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ShopPage(),
);
}
}
class ShopPage extends StatefulWidget {
@override
State<ShopPage> createState() => _ShopPageState();
}
class _ShopPageState extends State<ShopPage> {
List<String> imageList = [
"https://picsum.photos/id/100/200/200",
"https://picsum.photos/id/101/200/200"
];
int selectedIndex = 0;
@override
Widget build(BuildContext context) {
print("ShopPage 그림 그려짐");
return Scaffold(
appBar: AppBar(title: Text("쇼핑카트")),
body: Column(
children: [
//1. 이미지를 건들이고 이미지의 크기를 강제로 바꾸려면 부모에 aspectRtio 다른것들은 sized 박스
AspectRatio(
aspectRatio: 3 / 2,
child: Image.network(
imageList[selectedIndex],
fit: BoxFit.cover,
),
),
//2. 버튼2개
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(
width: 70,
height: 70,
//decoration을 사용하면 여기에 color를 지정해야된다 container에 color를 사용못하게 막았다 그냥 문법
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.circular(20),
),
child: IconButton(
onPressed: () {
selectedIndex = 0;
print("selectedIndex : $selectedIndex ");
setState(() {});
},
icon: Icon(Icons.access_alarm_sharp)),
),
Container(
width: 70,
height: 70,
//decoration을 사용하면 여기에 color를 지정해야된다 container에 color를 사용못하게 막았다 그냥 문법
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(20),
),
child: IconButton(
onPressed: () {
selectedIndex = 1;
print("selectedIndex : $selectedIndex ");
setState(() {});
},
icon: Icon(Icons.accessibility_sharp)),
),
],
),
],
);
}
}
해당 코드는 버튼 두 개를 이용해 각각의 이미지를 불러오도록 하는 것이다.
현재의 코드에는 ShopPage 메서드에
StatefulWidget 이 설정되어있다. 그렇기 때문에 버튼을 누른다면 ShopPage의 해당 영역 부분만 reloading 된다. 만약 StatefulWidget 이 main으로 실행되는 MyApp에 적용되어 있다면 ShopPage 뿐만 아니라 이후 작성하는 다른 코드 부분의 영역에도 적용되어 화면 전체가 reloading 되는 것이다.4. 사용 방식
extends StatefulWidget 부분에 커서를 올리고 alt + Enter 를 누르면 그림과 같이 나오고 상태 메서드를 생성하게 된다.
이를 각각 버튼마다 status 를 설정해놓고 버튼을 누를 때 이벤트를 발생시키는 영역에
onPressed: () {
selectedIndex = 1;
print("selectedIndex : $selectedIndex ");
setState(() {});다음과 같이
setState(() {}); 를 넣어주면 상태가 적용되며 화면이 부분 reloading 된다.5. 차이점 요약
ㅤ | StatelessWidget | StatefulWidget |
상태 관리 | 상태를 유지하지 않음 | 상태를 유지하고 변경 가능 |
UI 갱신 | UI가 고정되어 변화하지 않음 | setState()로 상태 변경 시 UI 갱신 |
라이프사이클 | 없음 | 있음 ( initState(), dispose()) |
사용 시점 | 정적인 UI, 변하지 않는 값 | 동적인 UI, 상태 변화가 필요한 경우 |
- StatelessWidget은 정적인 데이터를 표시할 때 적합하고,
- StatefulWidget은 상태 변화가 필요한 동적인 UI를 구현할 때 적합합니다.
이러한 차이를 통해, 애플리케이션의 요구 사항에 맞는 위젯을 선택할 수 있습니다.
Share article