1. Stateful Widget 정의
- 상태를 가질 수 있는 위젯
- 상태 변화에 따라 UI를 업데이트할 수 있음
2. 구성
1. StatefulWidget 클래스
createState()
메서드로 State 객체 생성
2. State 클래스
- 상태 관리 및 UI 업데이트 담당
setState()
호출 시 화면 재구성
3. 코드 분석
1. HomePage
: StatefulWidget 정의
- 상태를 가지며, 상태 변화에 따라 UI 갱신
2. _HomePageState
: State 클래스
num
변수로 상태 관리
setState()
호출로 UI 업데이트
- UI 업데이트 과정
- 버튼 클릭 →
num++
실행 setState()
호출 →build()
재실행- 화면에
num
값 갱신
3. 예시 코드
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("MyApp build....1");
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
State<HomePage> createState() => _HomePageState(); // HomePage의 상태를 관리할 State 객체(_HomePageState) 생성
}
class _HomePageState extends State<HomePage> {
int num = 1; // 상태 변수 num, 초기 값은 1
@override
Widget build(BuildContext context) {
print("HomePage build....2"); // HomePage가 빌드될 때마다 출력
return Scaffold(
body: Column(
children: [
Expanded(
child: Center(
child: Container(
child: Text("$num"), // 화면에 num 값 출력
),
),
),
Expanded(
child: Center(
child: Container(
child: ElevatedButton(
onPressed: () {
num++; // 버튼 클릭 시 num 값을 1 증가
setState(() {}); // 상태 변화 알리고 UI를 갱신하도록 Flutter에 요청
print("num: $num"); // 상태 변화 후 num 값 출력
},
child: Icon(Icons.add), // 버튼에 더하기 아이콘 추가
),
),
),
),
],
),
);
}
}

현재 HomePage가 Stateful 이여서 setState를 하게 되면 Homepage의 모든 자식들이 다시 그려지는 문제가 존재
>> 하나의 BuildContext내에서 모든 그림을 관리하고 있어 생기는 문제

4. 단점을 보완한 예시 코드
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("HomePage build..."); // HomePage가 빌드될 때 출력
return Scaffold(
body: Middle(), // Middle 위젯을 화면에 표시
);
}
}
class Middle extends StatefulWidget {
const Middle({
super.key,
});
@override
State<Middle> createState() => _MiddleState(); // Middle 상태 객체 생성
}
class _MiddleState extends State<Middle> {
// 상태 변수 num, 초기 값은 1
int num = 1;
// 상태 변경 메서드 increase()
increase() {
num++; // num 값 증가
setState(() {}); // 상태가 변경되었음을 알리고 UI 갱신
}
@override
Widget build(BuildContext context) {
print("Middle build..."); // Middle이 빌드될 때 출력
return Column(
children: [
Expanded(
child: Top(num), // 상태(num)를 Top 위젯에 전달
),
Expanded(
child: Bottom(increase), // 행위(increase 메서드)를 Bottom 위젯에 전달
),
],
);
}
}
class Bottom extends StatelessWidget {
final Function increase; // increase 메서드를 받아올 변수
Bottom(this.increase); // 생성자에서 increase 메서드 받기
@override
Widget build(BuildContext context) {
print("Bottom build..."); // Bottom이 빌드될 때 출력
return Center(
child: Container(
child: ElevatedButton(
onPressed: () {
increase(); // 버튼 클릭 시 increase() 호출
},
child: Icon(Icons.add), // 버튼에 더하기 아이콘 추가
),
),
);
}
}
class Top extends StatelessWidget {
final int num; // num 값을 받아올 변수
Top(this.num); // 생성자에서 num 값을 받기
@override
Widget build(BuildContext context) {
print("Top build..."); // Top이 빌드될 때 출력
return Center(
child: Container(
child: Text(
"$num",
style: TextStyle(fontSize: 50), // num 값을 화면에 표시
),
),
);
}
}
Middle()을 생성해 BuildContext를 분리하여 따로 관리
>> 필요한 곳만 다시 Build함

Share article