본문 바로가기
Flutter/Widget

플러터에서 InheritedWidget: 초보자를 위한 간단한 가이드

by Maccrey Coding 2024. 10. 25.
728x90
반응형

1. InheritedWidget이란?

InheritedWidget은 Flutter에서 데이터를 트리구조로 전달하는 방법 중 하나입니다. 간단히 말해, 한 위젯에서 데이터를 생성하고, 그 데이터를 자식 위젯들이 어디서든 접근할 수 있게 합니다. 이 방식은 상태 공유가 필요한 경우에 유용합니다. 예를 들어, 여러 화면에서 로그인 상태를 공유하거나, 테마 설정을 위젯 트리 전체에서 유지하고 싶을 때 사용할 수 있어요.

2. 언제 InheritedWidget을 사용해야 할까?

다음과 같은 경우 InheritedWidget을 사용하는 것이 좋습니다:

  • 위젯 트리의 여러 곳에서 동일한 데이터에 접근할 필요가 있을 때
  • 전역 상태 관리가 필요할 때
  • 상태를 위젯 트리의 상위에서 하위로 전달해야 할 때

하지만, 요즘은 상태 관리 도구로 ProviderRiverpod 같은 패키지가 더 많이 쓰이기 때문에, 복잡한 앱에서는 InheritedWidget보다 더 나은 대안이 될 수 있습니다.

3. InheritedWidget의 기본 구조

InheritedWidget을 이해하기 위해 먼저 기본적인 구조를 알아볼게요. InheritedWidget을 직접 상속받아 구현하며, 보통 상태를 관리하는 StatefulWidget과 함께 사용됩니다.

class MyInheritedWidget extends InheritedWidget {
  final int data;

  MyInheritedWidget({required this.data, required Widget child}) : super(child: child);

  // 데이터가 변경되었을 때 하위 위젯을 리빌드할지 여부를 정의
  @override
  bool updateShouldNotify(covariant InheritedWidget oldWidget) {
    return true; // 언제나 리빌드함
  }

  // 하위 위젯들이 데이터에 접근할 수 있도록 하는 메서드
  static MyInheritedWidget? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();
  }
}

이 코드는 기본적인 InheritedWidget 클래스입니다. data라는 값을 생성자에서 받고, 이를 자식 위젯들에게 전달합니다.

4. InheritedWidget 예제

이제 간단한 예제를 통해 InheritedWidget을 어떻게 사용하는지 살펴볼게요.

예제: 숫자 카운터 앱

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('InheritedWidget 예제')),
        body: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

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

  @override
  Widget build(BuildContext context) {
    return CounterProvider(
      counter: _counter,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text('카운터 값:'),
          CounterText(),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: _incrementCounter,
            child: Text('카운터 증가'),
          ),
        ],
      ),
    );
  }
}

class CounterProvider extends InheritedWidget {
  final int counter;

  CounterProvider({required this.counter, required Widget child}) : super(child: child);

  @override
  bool updateShouldNotify(covariant InheritedWidget oldWidget) {
    return true;
  }

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

class CounterText extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final provider = CounterProvider.of(context);
    return Text(provider?.counter.toString() ?? '0', style: TextStyle(fontSize: 24));
  }
}

코드 설명

  1. CounterProvider: InheritedWidget을 상속받아, 카운터 값을 전달하는 역할을 합니다.
  2. CounterText: CounterProvider에서 전달된 카운터 값을 받아 화면에 표시합니다.
  3. MyHomePage: 카운터 값을 증가시키고, 이를 CounterProvider로 자식 위젯들에게 전달합니다.

5. InheritedWidget 사용 시 주의점

  • InheritedWidget은 데이터가 변경되면 트리의 모든 자식 위젯을 리빌드합니다. 따라서 너무 빈번하게 변경되는 상태는 다른 상태 관리 도구(예: Provider)를 사용하는 것이 성능에 더 좋을 수 있습니다.
  • InheritedWidget을 사용할 때는 updateShouldNotify 메서드를 통해 리빌드를 효율적으로 관리해야 합니다. 이 메서드에서 true를 반환하면 자식 위젯들이 모두 다시 그려집니다.

InheritedWidget은 Flutter에서 상태를 공유할 때 유용한 도구입니다. 이 방법은 상대적으로 간단한 상태를 전달할 때 적합하며, 복잡한 앱에서는 더 발전된 상태 관리 도구와 함께 사용할 수 있습니다. 이 글에서는 기본적인 예제와 개념을 다뤘지만, 더 복잡한 상태 관리 방식도 있으니 추후 학습해보는 것을 추천드립니다!

 

공감과 댓글은 저에게 큰 힘이 됩니다.

Starting Google Play App Distribution! "Tester Share" for Recruiting 20 Testers for a Closed Test.

 

Tester Share [테스터쉐어] - Google Play 앱

Tester Share로 Google Play 앱 등록을 단순화하세요.

play.google.com

 

 

728x90
반응형