StatefulWidget

하요·2024년 7월 6일
0

Flutter State Management

목록 보기
2/7
post-thumbnail

Flutter에서 간단한 로컬 상태 관리하기: StatefulWidget

StatefulWidget은 Flutter에서 상태를 관리하는 기본적인 방법 중 하나로, 상태가 변할 수 있는 위젯을 만들 때 사용됩니다. StatefulWidget을 통해 동적인 UI 업데이트가 가능하며, 이를 이용해 다양한 상태 기반 인터랙션을 구현할 수 있습니다.

주요 개념

  • StatefulWidget: 상태가 변할 수 있는 위젯을 정의합니다. 상태 변화에 따라 UI를 재구성합니다.
  • State 클래스: StatefulWidget의 상태를 나타내며, 상태 변화를 관리합니다. State 클래스는 StatefulWidget과 분리되어 상태를 독립적으로 관리할 수 있습니다.

주요 속성 및 메서드

  • initState: State 클래스의 초기화 메서드로, 상태 초기화를 수행합니다. State 객체가 처음 생성될 때 한 번 호출됩니다.
  • setState: 상태를 변경하고, UI를 다시 빌드하도록 하는 메서드입니다. 상태가 변경될 때마다 호출합니다.
  • dispose: State 객체가 소멸될 때 호출되는 메서드로, 리소스를 정리하는 데 사용됩니다.

주요 활용도

  • 로컬 상태 관리: 간단한 상태 관리를 할 때 유용합니다. 예를 들어, 버튼 클릭 수 카운트, 입력 필드 값 등.
  • 동적인 UI 업데이트: 상태 변경에 따라 UI를 동적으로 업데이트할 수 있습니다.

코드 예제

아래 예제는 간단한 카운터 앱을 통해 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),
      ),
    );
  }
}

Prop Drilling 문제

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 해결 방법

Prop Drilling 문제를 해결하기 위해 Flutter에서는 다양한 상태 관리 도구를 제공합니다:

  • InheritedWidget: 상위 위젯에서 하위 위젯으로 데이터를 전달할 때 중간 위젯을 거치지 않고 데이터를 전달할 수 있습니다.
  • Provider: Flutter 팀에서 권장하는 상태 관리 도구로, DI(Dependency Injection)와 반응형 상태 관리를 제공합니다.
  • Riverpod: Provider의 개선된 버전으로, 더 안전하고 테스트하기 쉬운 상태 관리를 제공합니다.
  • BLoC (Business Logic Component): 이벤트 기반 상태 관리 패턴으로, 상태의 예측 가능성을 높여줍니다.

추가 팁

  • 성능 최적화: setState는 필요한 경우에만 호출하여 불필요한 위젯 빌드를 최소화해야 합니다.
  • 복잡한 상태 관리: 앱의 상태가 여러 위젯 간에 공유되거나, 글로벌 상태 관리가 필요한 경우, Provider, BLoC, Riverpod와 같은 상태 관리 도구를 사용하는 것이 좋습니다.

관련 자료

추가 참고 리소스

profile
flutter 개발자(진)

0개의 댓글

관련 채용 정보