StatefulWidget
은 Flutter에서 상태를 관리하는 기본적인 방법 중 하나로, 상태가 변할 수 있는 위젯을 만들 때 사용됩니다. StatefulWidget
을 통해 동적인 UI 업데이트가 가능하며, 이를 이용해 다양한 상태 기반 인터랙션을 구현할 수 있습니다.
StatefulWidget
의 상태를 나타내며, 상태 변화를 관리합니다. State
클래스는 StatefulWidget
과 분리되어 상태를 독립적으로 관리할 수 있습니다.initState
: State
클래스의 초기화 메서드로, 상태 초기화를 수행합니다. State
객체가 처음 생성될 때 한 번 호출됩니다.setState
: 상태를 변경하고, UI를 다시 빌드하도록 하는 메서드입니다. 상태가 변경될 때마다 호출합니다.dispose
: State
객체가 소멸될 때 호출되는 메서드로, 리소스를 정리하는 데 사용됩니다.아래 예제는 간단한 카운터 앱을 통해 StatefulWidget
의 사용 방법을 보여줍니다.
class CounterApp extends StatefulWidget {
_CounterAppState createState() => _CounterAppState();
}
class _CounterAppState extends State<CounterApp> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Counter App')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('You have pushed the button this many times:'),
Text('$_counter', style: Theme.of(context).textTheme.headline4),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
StatefulWidget
을 사용하여 상태를 관리할 때 발생할 수 있는 문제 중 하나는 Prop Drilling입니다. 이는 부모 위젯에서 자식 위젯으로 상태를 전달할 때 중간에 위치한 모든 위젯이 해당 속성을 전달받아야 하는 문제를 말합니다.
class ParentWidget extends StatefulWidget {
_ParentWidgetState createState() => _ParentWidgetState();
}
class _ParentWidgetState extends State<ParentWidget> {
String data = "Hello";
void updateData(String newData) {
setState(() {
data = newData;
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Prop Drilling Example')),
body: MiddleWidget(
data: data,
updateData: updateData,
),
);
}
}
class MiddleWidget extends StatelessWidget {
final String data;
final Function(String) updateData;
MiddleWidget({required this.data, required this.updateData});
Widget build(BuildContext context) {
return Column(
children: [
Text('Middle Widget'),
ChildWidget(
data: data,
updateData: updateData,
),
],
);
}
}
class ChildWidget extends StatelessWidget {
final String data;
final Function(String) updateData;
ChildWidget({required this.data, required this.updateData});
Widget build(BuildContext context) {
return Column(
children: [
Text('Data: $data'),
ElevatedButton(
onPressed: () {
updateData('Hello from Child');
},
child: Text('Update Data'),
),
],
);
}
}
Prop Drilling 문제를 해결하기 위해 Flutter에서는 다양한 상태 관리 도구를 제공합니다:
setState
는 필요한 경우에만 호출하여 불필요한 위젯 빌드를 최소화해야 합니다.Provider
, BLoC
, Riverpod
와 같은 상태 관리 도구를 사용하는 것이 좋습니다.