InheritedWidget

하요·2024년 7월 6일
0

Flutter State Management

목록 보기
3/7
post-thumbnail
post-custom-banner

Flutter에서 상태관리의 Prop Drilling 문제 해결: InheritedWidget

InheritedWidget은 Flutter에서 상위 위젯에서 하위 위젯으로 데이터를 전달할 때 사용하는 위젯입니다. InheritedWidget을 사용하면 트리의 중간 위젯들을 거치지 않고도 상태를 하위 위젯으로 전달할 수 있어 상태 관리에 유용합니다.

주요 개념

  • InheritedWidget: 상위 위젯에서 하위 위젯으로 데이터를 전달하는 역할을 합니다. 데이터가 변경되면 해당 데이터를 사용하는 모든 하위 위젯들이 다시 빌드됩니다.
  • of 메서드: InheritedWidget에서 데이터를 가져올 때 사용합니다. BuildContext를 통해 상위 InheritedWidget에 접근합니다.

InheritedWidget 특징

  • Prop Drilling 문제 해결: 중간 위젯들에게 속성을 계속 전달해야 하는 문제를 해결할 수 있습니다.
  • 상태 변경 및 갱신 별도 구현 필요: 자식 위젯의 접근만 도와줄 뿐, 상태 변경 및 위젯 갱신은 별도로 구현해야 합니다.
  • 위젯 트리 존재 여부 주의: 위젯 트리상에 InheritedWidget이 존재하지 않으면 런타임 에러가 발생할 수 있습니다.

자식 위젯의 독립성: 자식 위젯이 공유 상태나 메서드를 갖지 않아도 됩니다. 따라서 const 키워드를 사용할 수 있어 빌드 성능이 최적화됩니다.

실제 사용 예

  • MediaQuery, Theme.of 등 Flutter의 기본적인 위젯들도 InheritedWidget을 사용하여 구현되었습니다. 이를 통해 디바이스의 크기나 테마 설정 등에 쉽게 접근할 수 있습니다.

주요 속성 및 메서드

  • updateShouldNotify: InheritedWidget이 재빌드되어야 하는지를 결정하는 메서드입니다. 이전 데이터와 새로운 데이터를 비교하여 필요할 때만 하위 위젯들을 다시 빌드합니다.

주요 활용도

  • 전역 상태 관리: 간단한 전역 상태를 관리할 때 유용합니다. 예를 들어, 테마, 언어 설정 등.
  • 상태 공유: 여러 위젯에서 동일한 데이터를 필요로 할 때 중간 위젯을 거치지 않고 데이터를 공유할 수 있습니다.

코드 예제

아래 예제는 간단한 카운터 앱을 통해 InheritedWidget의 사용 방법을 보여줍니다.

class Counter extends InheritedWidget {
  final int count;
  final Function() increment;

  Counter({
    Key? key,
    required this.count,
    required this.increment,
    required Widget child,
  }) : super(key: key, child: child);

  static Counter? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<Counter>();
  }

  
  bool updateShouldNotify(Counter oldWidget) {
    return oldWidget.count != count;
  }
}

class CounterApp extends StatefulWidget {
  
  _CounterAppState createState() => _CounterAppState();
}

class _CounterAppState extends State<CounterApp> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  
  Widget build(BuildContext context) {
    return Counter(
      count: _counter,
      increment: _incrementCounter,
      child: Scaffold(
        appBar: AppBar(title: Text('Counter App')),
        body: Center(child: CounterDisplay()),
        floatingActionButton: FloatingActionButton(
          onPressed: _incrementCounter,
          tooltip: 'Increment',
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

class CounterDisplay extends StatelessWidget {
  
  Widget build(BuildContext context) {
    final counter = Counter.of(context);

    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('You have pushed the button this many times:'),
        Text('${counter?.count}', style: Theme.of(context).textTheme.headline4),
      ],
    );
  }
}

Prop Drilling 문제 해결

InheritedWidget은 Prop Drilling 문제를 효과적으로 해결할 수 있는 도구입니다. 부모 위젯에서 자식 위젯으로 상태를 전달할 때 중간에 위치한 위젯들이 불필요한 속성을 전달받지 않도록 합니다.

문제점 해결

  • 중간 위젯의 불필요한 속성 전달 방지: 데이터가 필요한 위젯만 데이터를 직접 받아 사용합니다.
  • 코드의 가독성 향상: 위젯의 역할이 명확해지고, 코드가 단순해집니다.
  • 유지보수 용이: 데이터 구조가 변경되더라도 중간 위젯을 수정할 필요가 없습니다.

추가 팁

  • 성능 최적화: updateShouldNotify 메서드를 적절히 구현하여 불필요한 위젯 빌드를 최소화합니다.
  • 복잡한 상태 관리: 앱이 커지고 상태가 복잡해질 경우, Provider, Riverpod, BLoC 등 더 강력한 상태 관리 도구를 사용하는 것이 좋습니다.

관련 자료

추가 참고 리소스

profile
flutter 개발자(진)
post-custom-banner

0개의 댓글