1. StatelessWidget vs StatefulWidget
Flutter에서는 UI를 직접 그리지 않는 대신 위젯들을 겹겹이 쌓아 전체 UI를 구현합니다.
화면에 보이는 텍스트, 이미지, 버튼 등 모든 것이 위젯으로 구성되어 있습니다.
이러한 위젯은 크게 두 가지로 나눌 수 있는데요.
바로 StatelessWidget과 StatefulWidget입니다.
2. build()
여기서 알아야 할 개념이 있습니다.
바로 build()인데요.
위젯이 화면을 그리는 방법을 정의하는 함수입니다.
Flutter에서 모든 UI는 위젯 트리(위젯들로 이루어진 트리 구조)로 구성되어 있습니다.
build()는 그 트리를 만들어주는 설계도 역할을 합니다.
즉, build()는 버튼과 텍스트를 화면에 어떻게 배치할지를 정의하며,
setState()로 상태가 변경되면 다시 호출돼서 새로운 UI를 그립니다.
setState()는 아래에서 다시 다룰게요.
3. StatelessWidget
1) StatelessWidget이란?
Flutter의 공식 문서에 따르면 StatelessWidget은 이렇게 정의하고 있습니다.
A widget that does not require mutable state(변경 가능한 상태가 필요 없는 위젯)
쉽게 말해서 StatelessWidget은 상태가 필요 없는 위젯입니다.
상태가 필요 없기 때문에 상태가 변하지 않는다는 특징(immutable)을 가지고 있습니다.
즉, 내부에 변경 가능한 상태를 갖지 않아서 스스로 UI를 바꾸지 않습니다.
다만 부모 위젯이 바뀌거나 외부 상태가 변경(다크모드 전환)되면 다시 build 될 수는 있습니다.
이러한 StatelessWidget은 주로 단순 텍스트, 버튼 등 상태 변화가 필요 없는 컴포넌트를 구성할 때 사용합니다.
2) StatelessWidget에서 build()가 호출되는 상황
StatelessWidget은 상태가 없다고 해서 절대 다시 안 그려지는 것이 아닙니다.
특정한 상황에서 build()가 호출될 수 있는데요.
이는 세 가지 상황에서 호출됩니다.
1. 위젯이 트리에 처음 추가될 때
- 처음 화면에 위젯이 등장할 때 build()가 실행됩니다.
2. 부모 위젯이 새로운 값으로 다시 build 할 때
- 내 위젯 자체는 변경되지 않았어도 부모가 내 위젯을 새로 만들면 내 위젯도 다시 build()를 호출합니다.
3. 의존 중인 InheritedWidget이 변경될 때
- 다크모드 전환할 때 ThemeData가 변경되며, 그와 함께 context 값도 바뀌므로 build()를 다시 호출합니다.
그 외에는 절대로 다시 build 되지 않습니다.
3) 예제 코드
class DescriptionText extends StatelessWidget {
const DescriptionText({super.key});
@override
Widget build(BuildContext context) {
return Text('버튼을 클릭하면 1씩 증가합니다.', style: TextStyle(fontSize: 16));
}
}
DescriptionText라는 이름의 새로운 위젯 클래스를 정의하고 있습니다.
StatelessWidget을 상속받아 상태가 변하지 않는 고정된 위젯입니다.
4) key가 필요한 이유
해당 코드를 VSCode에 복붙하고,
constDesccriptionText({super.key});
코드를 제거하면 파란 줄이 뜨면서 이런 메시지가 나옵니다.

번역하면 public widget의 생성자에는 'key'라는 이름의 named parameter가 있어야 한다고 합니다.
이를 수정하지 않고 실행하면 오류가 발생하지는 않지만 Dart/Flutter의 필수는 아니지만 권장되는 구조라서 따르는 게 좋습니다.
그렇다면 왜 key가 필요한걸까요?
먼저 public widget은 다른 파일이나 클래스에서 불러 쓸 수 있는 위젯으로 재사용을 전제로 만든 위젯입니다.
또한, Flutter는 UI를 자주 rebuild 하기 때문에 이 위젯이 이전에 쓰던 위젯인지를 판단하기 위해서는 key값이 필요합니다.
만약 key가 없으면 불필요한 rebuild를 하거나 새로 생긴 위젯인지, 기존 위젯인지 구별하지 못해 상태 꼬임, 성능 저하가 발생할 수 있습니다.
그렇기 때문에 가능하면 key를 받을 수 있게 만드는 것이 좋습니다.
5) 성능 팁
1. const 생성자, const 위젯 사용하기
const를 붙이면 위젯이 불변(immutable) 임을 Flutter가 알게 되어 재사용, 캐싱, rebuild 생략 등 최적화를 적용할 수 있습니다.
2. build() 안에 위젯을 많이 만들지 않기
build()는 위젯이 다시 그려질 때마다 호출되는 함수입니다.
그 안에 복잡하고 무거운 위젯을 많이 만들면 성능 저하가 발생할 수 있습니다.
가능하면 재사용 가능한 작은 위젯으로 분리하거나 불변인 부분은 StatelessWidget으로 따로 빼는 게 더 효율적입니다.
3. 복잡한 스타일은 CustomPaint 등으로 대체하기
그림자, 테두리, 배경색 등을 표현하기 위해 Container를 여러 개 겹쳐 쓰는 경우가 있습니다.
하지만 이는 비효율적일 수 있습니다.
이럴 땐 CustonPaint나 DecoratedBox 같은 가벼운 위젯을 사용하는 게 더 좋습니다.
4. 자주 rebuild 되면 작게 쪼개기
화면 전체가 자주 rebuild 된다면 변화가 필요한 부분만 효율적으로 업데이트할 수 있도록 따로 위젯으로 분리하는 것이 좋습니다.
5. 함수 대신 위젯 클래스로 분리하기
함수는 상태가 변경될 때마다 항상 다시 실행됩니다.
하지만 위젯은 구조가 동일하다면 Flutter가 변경된 부분만 효율적으로 변경할 수 있습니다.
그래서 자주 바뀌지 않는 UI는 함수보다 위젯 클래스로 분리하는 게 성능에 더 유리합니다.
하지만 만약, 상태가 필요한 경우에는 어떻게 할까요?
바로 뒤에 나올 개념인 StatefulWidget을 사용하면 됩니다.
공식 문서에도 동적으로 변경될 수 있는 구성의 경우에는 StatefulWidget을 사용하라고 안내되어 있습니다.
즉, 시간에 따라 바뀌거나 사용자 액션에 반응하거나 (버튼 클릭), 시스템 상태에 따라 달라지는 UI는 StatefulWidget을 사용합니다.
4. StatefulWidget
1) StatefulWidget이란?
공식문서에서는 이렇게 정의하고 있습니다.
A widget that has mutable state. (변경 가능한 상태를 가진 위젯)
쉽게 말해서 상태가 있는 위젯으로 내부 상태가 변할 수 있는 UI를 만들 때 사용합니다.
사용자가 버튼을 클릭하면 숫자가 증가한다거나, 텍스트 입력값에 따라 화면이 바뀐다거나
애니메이션, 슬라이더 등 동적인 UI를 만들기 위해서는 StatefulWidget이 필요합니다.
2) StatefulWidget 구성 요소
먼저 StatefulWidget은 기본적으로 두 가지 클래스로 구성되어 있습니다.
StatefulWidget 클래스와 State<T> 클래스입니다.
StatefulWidget은 변경 가능한 UI 컴포넌트이며,
Flutter는 이 클래스를 통해 해당 위젯이 상태가 있다는 것을 인식합니다.
UI의 이름과 외부에서 받을 값을 정의하고,
createState() 메서드를 통해 연결될 State 클래스를 생성합니다.
State<T> 클래스는 실제 상태 값과 UI를 담당하는 부분입니다.
실제 상태 변수를 선언하고,
상태 변경 시 호출할 setState() 함수도 있으며,
화면을 그리는 build() 함수,
위젯의 라이프사이클 관리를 하는 역할을 합니다.
3) setState()
setState()는 StatefulWidget 안에서 UI를 다시 그리도록 요청하는 함수입니다.
즉, 상태가 바뀌었음을 Flutter에게 알려주고,
변경된 상태를 반영한 새로운 UI를 다시 build() 하도록 트리거 역할을 합니다.
Flutter는 단순히 변수 값이 바뀌었다고 화면을 자동으로 다시 그리지는 않습니다.
그렇기 때문에 상태 변경을 UI에 반영하려면 반드시 setState() 안에 작성해야 합니다.
setState()를 호출하면, State가 변경됐음을 감지하고,
해당 위젯의 build() 함수를 다시 호출해 새로운 UI를 구성합니다.
4) 예제 코드
// 상태를 가지는 StatefulWidget
class CounterPage extends StatefulWidget {
const CounterPage({super.key});
@override
State<CounterPage> createState() => _CounterPageState();
}
class _CounterPageState extends State<CounterPage> {
// _count는 상태
int _counter = 0;
// 상태를 바꾸는 함수
void _incrementCounter() {
// setState()안에서 상태를 바꾸면 UI가 자동으로 갱신
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Stateful Counter')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
DescriptionText(), // StatelessWidget 사용
const SizedBox(height: 16),
Text(
'$_counter',
style: const TextStyle(fontSize: 36, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _incrementCounter,
child: const Text('증가'),
),
],
),
),
);
}
}
5) Widget의 const
const는 컴파일 타임에 고정된 값으로 위젯에 const를 붙이면 한 번 만들어진 위젯 인스턴스를 재사용할 수 있습니다.
왜 Widget에 const가 필요한 걸까요?
크게 세 가지 이유가 있습니다.
먼저 성능 향상입니다.
Flutter는 화면을 자주 rebuild 합니다.
하지만 const 위젯은 한 번 만들어지면 다시 만들지 않고 재사용합니다.
즉, const를 사용하면 불필요한 rebuild 비용을 줄여 UI 성능이 좋아집니다.
두 번째로 메모리를 절약할 수 있습니다.
const로 만든 위젯은 메모리에서 단 하나의 인스턴스만 생성됩니다.
같은 내용의 위젯을 여러 번 만들어도 메모리는 하나만 사용하기 때문에 메모리를 절약할 수 있습니다.
마지막으로 코드의 안정성을 보장한다는 점인데요.
const는 immutable(불변) 객체만 만들 수 있기 때문에 실수로 속성 값을 바꾸는 버그를 막아 안정적인 코드 작성을 할 수 있습니다.
6) 성능 팁
1) 상태는 가능한 leaf에 몰아라
leaf는 위젯 트리 구조의 끝에 있는 노드를 말합니다.
즉, 더 이상 자식 위젯이 없는 마지막 위젯을 의미합니다.
전체 페이지를 StatefulWidget으로 만들지 말고, 변화가 필요한 부분만 Stateful로 분리하는 것이 좋습니다.
이와 같은 구조라면 리빌드 범위를 줄여 성능을 높일 수 있습니다.
2. build() 안에 위젯을 많이 만들지 않기
Stateless와 동일한 이유입니다.
build()는 위젯이 리빌드 될 때마다 호출되므로 가볍고 단순하게 유지하는 것이 좋습니다.
복잡한 로직이나 중복된 위젯 선언은 클래스로 따로 빼는 것이 좋습니다.
3) 변하지 않는 UI는 const로 재사용
const는 위에서 설명했던 이유와 동일합니다.
4) build() 안에서 if/else로 위젯 구조 바꾸지 말고 속성만 바꿔서 조건처리하자
Flutter는 화면을 다시 그릴 때 이전 UI와 얼마나 달라졌는지 비교해서 필요한 부분만 다시 그립니다.
그런데 if/else로 UI 구조가 완전히 달라지면 아예 다른 UI라고 인식하기 때문에 전체를 다시 그립니다.
이는 성능에 좋지 않습니다.
Widget build(BuildContext context) {
if (isDarkMode) {
return Container(color: Colors.black);
} else {
return Column(children: [Text('라이트모드입니다')]);
}
}
위 코드는 Container와 Column이라는 서로 다른 위젯을 번갈아 만들고 있습니다.
Flutter에서는 완전히 다른 구조라고 생각하여 전체를 다시 그리게 됩니다.
Widget build(BuildContext context) {
return Container(
color: isDarkMode ? Colors.black : Colors.white,
child: Text(isDarkMode ? '다크모드입니다' : '라이트모드입니다'),
);
}
이 코드는 Container와 Text를 그대로 유지하고, 변경되는 것은 색깔과 텍스트라는 속성입니다.
Flutter에서는 동일한 구조라고 인식하여 속성만 변경하여 다시 그리기 때문에 더욱 빠르고 효율적입니다.
요약하자면 UI가 바뀔 일이 없다면 StatelessWidget을,
UI가 바뀐다면 StatefulWidget을 사용하는 것이 적합합니다.
5. 참고자료
https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html
StatelessWidget class - widgets library - Dart API
A widget that does not require mutable state. A stateless widget is a widget that describes part of the user interface by building a constellation of other widgets that describe the user interface more concretely. The building process continues recursively
api.flutter.dev
https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html
StatefulWidget class - widgets library - Dart API
A widget that has mutable state. State is information that (1) can be read synchronously when the widget is built and (2) might change during the lifetime of the widget. It is the responsibility of the widget implementer to ensure that the State is promptl
api.flutter.dev
'Flutter' 카테고리의 다른 글
[Flutter] Riverpod 상태 관리부터 개념 정리까지 (0) | 2025.04.11 |
---|---|
[Dart] 조건문 (if, if-else, switch) (0) | 2025.03.10 |
[Dart] 연산자 (Operators) (0) | 2025.03.10 |
[Dart] 데이터 타입 (0) | 2025.03.10 |
[Dart] 반복문(for, for-in, while, do while) (0) | 2025.03.07 |
1. StatelessWidget vs StatefulWidget
Flutter에서는 UI를 직접 그리지 않는 대신 위젯들을 겹겹이 쌓아 전체 UI를 구현합니다.
화면에 보이는 텍스트, 이미지, 버튼 등 모든 것이 위젯으로 구성되어 있습니다.
이러한 위젯은 크게 두 가지로 나눌 수 있는데요.
바로 StatelessWidget과 StatefulWidget입니다.
2. build()
여기서 알아야 할 개념이 있습니다.
바로 build()인데요.
위젯이 화면을 그리는 방법을 정의하는 함수입니다.
Flutter에서 모든 UI는 위젯 트리(위젯들로 이루어진 트리 구조)로 구성되어 있습니다.
build()는 그 트리를 만들어주는 설계도 역할을 합니다.
즉, build()는 버튼과 텍스트를 화면에 어떻게 배치할지를 정의하며,
setState()로 상태가 변경되면 다시 호출돼서 새로운 UI를 그립니다.
setState()는 아래에서 다시 다룰게요.
3. StatelessWidget
1) StatelessWidget이란?
Flutter의 공식 문서에 따르면 StatelessWidget은 이렇게 정의하고 있습니다.
A widget that does not require mutable state(변경 가능한 상태가 필요 없는 위젯)
쉽게 말해서 StatelessWidget은 상태가 필요 없는 위젯입니다.
상태가 필요 없기 때문에 상태가 변하지 않는다는 특징(immutable)을 가지고 있습니다.
즉, 내부에 변경 가능한 상태를 갖지 않아서 스스로 UI를 바꾸지 않습니다.
다만 부모 위젯이 바뀌거나 외부 상태가 변경(다크모드 전환)되면 다시 build 될 수는 있습니다.
이러한 StatelessWidget은 주로 단순 텍스트, 버튼 등 상태 변화가 필요 없는 컴포넌트를 구성할 때 사용합니다.
2) StatelessWidget에서 build()가 호출되는 상황
StatelessWidget은 상태가 없다고 해서 절대 다시 안 그려지는 것이 아닙니다.
특정한 상황에서 build()가 호출될 수 있는데요.
이는 세 가지 상황에서 호출됩니다.
1. 위젯이 트리에 처음 추가될 때
- 처음 화면에 위젯이 등장할 때 build()가 실행됩니다.
2. 부모 위젯이 새로운 값으로 다시 build 할 때
- 내 위젯 자체는 변경되지 않았어도 부모가 내 위젯을 새로 만들면 내 위젯도 다시 build()를 호출합니다.
3. 의존 중인 InheritedWidget이 변경될 때
- 다크모드 전환할 때 ThemeData가 변경되며, 그와 함께 context 값도 바뀌므로 build()를 다시 호출합니다.
그 외에는 절대로 다시 build 되지 않습니다.
3) 예제 코드
class DescriptionText extends StatelessWidget {
const DescriptionText({super.key});
@override
Widget build(BuildContext context) {
return Text('버튼을 클릭하면 1씩 증가합니다.', style: TextStyle(fontSize: 16));
}
}
DescriptionText라는 이름의 새로운 위젯 클래스를 정의하고 있습니다.
StatelessWidget을 상속받아 상태가 변하지 않는 고정된 위젯입니다.
4) key가 필요한 이유
해당 코드를 VSCode에 복붙하고,
constDesccriptionText({super.key});
코드를 제거하면 파란 줄이 뜨면서 이런 메시지가 나옵니다.

번역하면 public widget의 생성자에는 'key'라는 이름의 named parameter가 있어야 한다고 합니다.
이를 수정하지 않고 실행하면 오류가 발생하지는 않지만 Dart/Flutter의 필수는 아니지만 권장되는 구조라서 따르는 게 좋습니다.
그렇다면 왜 key가 필요한걸까요?
먼저 public widget은 다른 파일이나 클래스에서 불러 쓸 수 있는 위젯으로 재사용을 전제로 만든 위젯입니다.
또한, Flutter는 UI를 자주 rebuild 하기 때문에 이 위젯이 이전에 쓰던 위젯인지를 판단하기 위해서는 key값이 필요합니다.
만약 key가 없으면 불필요한 rebuild를 하거나 새로 생긴 위젯인지, 기존 위젯인지 구별하지 못해 상태 꼬임, 성능 저하가 발생할 수 있습니다.
그렇기 때문에 가능하면 key를 받을 수 있게 만드는 것이 좋습니다.
5) 성능 팁
1. const 생성자, const 위젯 사용하기
const를 붙이면 위젯이 불변(immutable) 임을 Flutter가 알게 되어 재사용, 캐싱, rebuild 생략 등 최적화를 적용할 수 있습니다.
2. build() 안에 위젯을 많이 만들지 않기
build()는 위젯이 다시 그려질 때마다 호출되는 함수입니다.
그 안에 복잡하고 무거운 위젯을 많이 만들면 성능 저하가 발생할 수 있습니다.
가능하면 재사용 가능한 작은 위젯으로 분리하거나 불변인 부분은 StatelessWidget으로 따로 빼는 게 더 효율적입니다.
3. 복잡한 스타일은 CustomPaint 등으로 대체하기
그림자, 테두리, 배경색 등을 표현하기 위해 Container를 여러 개 겹쳐 쓰는 경우가 있습니다.
하지만 이는 비효율적일 수 있습니다.
이럴 땐 CustonPaint나 DecoratedBox 같은 가벼운 위젯을 사용하는 게 더 좋습니다.
4. 자주 rebuild 되면 작게 쪼개기
화면 전체가 자주 rebuild 된다면 변화가 필요한 부분만 효율적으로 업데이트할 수 있도록 따로 위젯으로 분리하는 것이 좋습니다.
5. 함수 대신 위젯 클래스로 분리하기
함수는 상태가 변경될 때마다 항상 다시 실행됩니다.
하지만 위젯은 구조가 동일하다면 Flutter가 변경된 부분만 효율적으로 변경할 수 있습니다.
그래서 자주 바뀌지 않는 UI는 함수보다 위젯 클래스로 분리하는 게 성능에 더 유리합니다.
하지만 만약, 상태가 필요한 경우에는 어떻게 할까요?
바로 뒤에 나올 개념인 StatefulWidget을 사용하면 됩니다.
공식 문서에도 동적으로 변경될 수 있는 구성의 경우에는 StatefulWidget을 사용하라고 안내되어 있습니다.
즉, 시간에 따라 바뀌거나 사용자 액션에 반응하거나 (버튼 클릭), 시스템 상태에 따라 달라지는 UI는 StatefulWidget을 사용합니다.
4. StatefulWidget
1) StatefulWidget이란?
공식문서에서는 이렇게 정의하고 있습니다.
A widget that has mutable state. (변경 가능한 상태를 가진 위젯)
쉽게 말해서 상태가 있는 위젯으로 내부 상태가 변할 수 있는 UI를 만들 때 사용합니다.
사용자가 버튼을 클릭하면 숫자가 증가한다거나, 텍스트 입력값에 따라 화면이 바뀐다거나
애니메이션, 슬라이더 등 동적인 UI를 만들기 위해서는 StatefulWidget이 필요합니다.
2) StatefulWidget 구성 요소
먼저 StatefulWidget은 기본적으로 두 가지 클래스로 구성되어 있습니다.
StatefulWidget 클래스와 State<T> 클래스입니다.
StatefulWidget은 변경 가능한 UI 컴포넌트이며,
Flutter는 이 클래스를 통해 해당 위젯이 상태가 있다는 것을 인식합니다.
UI의 이름과 외부에서 받을 값을 정의하고,
createState() 메서드를 통해 연결될 State 클래스를 생성합니다.
State<T> 클래스는 실제 상태 값과 UI를 담당하는 부분입니다.
실제 상태 변수를 선언하고,
상태 변경 시 호출할 setState() 함수도 있으며,
화면을 그리는 build() 함수,
위젯의 라이프사이클 관리를 하는 역할을 합니다.
3) setState()
setState()는 StatefulWidget 안에서 UI를 다시 그리도록 요청하는 함수입니다.
즉, 상태가 바뀌었음을 Flutter에게 알려주고,
변경된 상태를 반영한 새로운 UI를 다시 build() 하도록 트리거 역할을 합니다.
Flutter는 단순히 변수 값이 바뀌었다고 화면을 자동으로 다시 그리지는 않습니다.
그렇기 때문에 상태 변경을 UI에 반영하려면 반드시 setState() 안에 작성해야 합니다.
setState()를 호출하면, State가 변경됐음을 감지하고,
해당 위젯의 build() 함수를 다시 호출해 새로운 UI를 구성합니다.
4) 예제 코드
// 상태를 가지는 StatefulWidget
class CounterPage extends StatefulWidget {
const CounterPage({super.key});
@override
State<CounterPage> createState() => _CounterPageState();
}
class _CounterPageState extends State<CounterPage> {
// _count는 상태
int _counter = 0;
// 상태를 바꾸는 함수
void _incrementCounter() {
// setState()안에서 상태를 바꾸면 UI가 자동으로 갱신
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Stateful Counter')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
DescriptionText(), // StatelessWidget 사용
const SizedBox(height: 16),
Text(
'$_counter',
style: const TextStyle(fontSize: 36, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _incrementCounter,
child: const Text('증가'),
),
],
),
),
);
}
}
5) Widget의 const
const는 컴파일 타임에 고정된 값으로 위젯에 const를 붙이면 한 번 만들어진 위젯 인스턴스를 재사용할 수 있습니다.
왜 Widget에 const가 필요한 걸까요?
크게 세 가지 이유가 있습니다.
먼저 성능 향상입니다.
Flutter는 화면을 자주 rebuild 합니다.
하지만 const 위젯은 한 번 만들어지면 다시 만들지 않고 재사용합니다.
즉, const를 사용하면 불필요한 rebuild 비용을 줄여 UI 성능이 좋아집니다.
두 번째로 메모리를 절약할 수 있습니다.
const로 만든 위젯은 메모리에서 단 하나의 인스턴스만 생성됩니다.
같은 내용의 위젯을 여러 번 만들어도 메모리는 하나만 사용하기 때문에 메모리를 절약할 수 있습니다.
마지막으로 코드의 안정성을 보장한다는 점인데요.
const는 immutable(불변) 객체만 만들 수 있기 때문에 실수로 속성 값을 바꾸는 버그를 막아 안정적인 코드 작성을 할 수 있습니다.
6) 성능 팁
1) 상태는 가능한 leaf에 몰아라
leaf는 위젯 트리 구조의 끝에 있는 노드를 말합니다.
즉, 더 이상 자식 위젯이 없는 마지막 위젯을 의미합니다.
전체 페이지를 StatefulWidget으로 만들지 말고, 변화가 필요한 부분만 Stateful로 분리하는 것이 좋습니다.
이와 같은 구조라면 리빌드 범위를 줄여 성능을 높일 수 있습니다.
2. build() 안에 위젯을 많이 만들지 않기
Stateless와 동일한 이유입니다.
build()는 위젯이 리빌드 될 때마다 호출되므로 가볍고 단순하게 유지하는 것이 좋습니다.
복잡한 로직이나 중복된 위젯 선언은 클래스로 따로 빼는 것이 좋습니다.
3) 변하지 않는 UI는 const로 재사용
const는 위에서 설명했던 이유와 동일합니다.
4) build() 안에서 if/else로 위젯 구조 바꾸지 말고 속성만 바꿔서 조건처리하자
Flutter는 화면을 다시 그릴 때 이전 UI와 얼마나 달라졌는지 비교해서 필요한 부분만 다시 그립니다.
그런데 if/else로 UI 구조가 완전히 달라지면 아예 다른 UI라고 인식하기 때문에 전체를 다시 그립니다.
이는 성능에 좋지 않습니다.
Widget build(BuildContext context) {
if (isDarkMode) {
return Container(color: Colors.black);
} else {
return Column(children: [Text('라이트모드입니다')]);
}
}
위 코드는 Container와 Column이라는 서로 다른 위젯을 번갈아 만들고 있습니다.
Flutter에서는 완전히 다른 구조라고 생각하여 전체를 다시 그리게 됩니다.
Widget build(BuildContext context) {
return Container(
color: isDarkMode ? Colors.black : Colors.white,
child: Text(isDarkMode ? '다크모드입니다' : '라이트모드입니다'),
);
}
이 코드는 Container와 Text를 그대로 유지하고, 변경되는 것은 색깔과 텍스트라는 속성입니다.
Flutter에서는 동일한 구조라고 인식하여 속성만 변경하여 다시 그리기 때문에 더욱 빠르고 효율적입니다.
요약하자면 UI가 바뀔 일이 없다면 StatelessWidget을,
UI가 바뀐다면 StatefulWidget을 사용하는 것이 적합합니다.
5. 참고자료
https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html
StatelessWidget class - widgets library - Dart API
A widget that does not require mutable state. A stateless widget is a widget that describes part of the user interface by building a constellation of other widgets that describe the user interface more concretely. The building process continues recursively
api.flutter.dev
https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html
StatefulWidget class - widgets library - Dart API
A widget that has mutable state. State is information that (1) can be read synchronously when the widget is built and (2) might change during the lifetime of the widget. It is the responsibility of the widget implementer to ensure that the State is promptl
api.flutter.dev
'Flutter' 카테고리의 다른 글
[Flutter] Riverpod 상태 관리부터 개념 정리까지 (0) | 2025.04.11 |
---|---|
[Dart] 조건문 (if, if-else, switch) (0) | 2025.03.10 |
[Dart] 연산자 (Operators) (0) | 2025.03.10 |
[Dart] 데이터 타입 (0) | 2025.03.10 |
[Dart] 반복문(for, for-in, while, do while) (0) | 2025.03.07 |