본문 바로가기

Flutter

Flutter InheritedWidget

https://api.flutter.dev/flutter/widgets/InheritedWidget-class.html

 

InheritedWidget class - widgets library - Dart API

Base class for widgets that efficiently propagate information down the tree. To obtain the nearest instance of a particular type of inherited widget from a build context, use BuildContext.dependOnInheritedWidgetOfExactType. Inherited widgets, when referenc

api.flutter.dev

복잡한 구조의 위젯 트리에서, 변화가 필요한 위젯이 트리의 마지막 부분에 위치하게 된다면 불필요한 데이터의 전달이 일어나게 된다. 이를 방지하기 위해 Flutter에는 InheritedWidget이라는 개념이 존재한다. InheritedWidget을 통해 효율적으로 데이터를 트리 아래로 전달할 수 있다.

 

Of 및 maybeOf 메서드 구현

관례적으로 InheritedWidget을 상속받는 클래스 내에서 두 가지 static 메서드인 of 와 maybeOf를 선언한다.

maybeOf에서는 BuildContext.dependOnInheritedWidgetOfExactType 메서드를 호출한다. 이는 클래스 내에서 범위 내에 위젯이 없을 때 자체 폴백 로직을 정의할 수 있게 한다.

 

일반적으로 of 메서드는 null을 허용하지 않는 인스턴스를 반환하고 assert를 통해 InheritedWidget을 찾을 수 없는 경우 오류를 발생시킨다. maybeOf는 nullable한 인스턴스를 반환한다. of 메서드는 maybeOf 메서드를 호출하여 정의하는 것이 일반적이다.

 

class FrogColor extends InheritedWidget {
  const FrogColor({
    super.key,
    required this.color,
    required super.child,
  });

  final Color color;

  static FrogColor? maybeOf(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<FrogColor>();
  }

  static FrogColor of(BuildContext context) {
    final FrogColor? result = maybeOf(context);
    assert(result != null, 'No FrogColor found in context');
    return result!;
  }

  @override
  bool updateShouldNotify(FrogColor oldWidget) => color != oldWidget.color;
}

updateShouldNotify 메서드는 데이터가 변경될 때 마다 위젯을 다시 빌드해야 하는 지에 대한 bool 값을 반환한다.

위의 코드는 데이터가 달라지는 경우에만 재빌드하겠다는 것을 의미한다.

 

of 또는 maybeOf 호출

class MyPage extends StatelessWidget {
  const MyPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FrogColor(
        color: Colors.green,
        child: Builder(
          builder: (BuildContext innerContext) {
            return Text(
              'Hello Frog',
              style: TextStyle(color: FrogColor.of(innerContext).color),
            );
          },
        ),
      ),
    );
  }
}

위의 코드는 InheritedWidget을 상속받은 클래스의 자식의 context를 통해 of 메서드를 호출하기 때문에 작동한다.

class MyOtherPage extends StatelessWidget {
  const MyOtherPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FrogColor(
        color: Colors.green,
        child: Text(
          'Hello Frog',
          style: TextStyle(color: FrogColor.of(context).color),
        ),
      ),
    );
  }
}

위의 코드는 부모 위젯의 context를 통해 of 메서드를 호출하기 때문에 작동하지 않고 assert에 걸리게 된다

'Flutter' 카테고리의 다른 글

Flutter MVVM Architecture  (0) 2023.05.30
Flutter Mockito를 이용한 API 통신 Unit Test  (0) 2023.04.19
뒤늦게 정리하는 Flutter riverpod 개념  (0) 2023.04.06
Debounce와 Throttle  (0) 2023.04.06
Flutter GoRouter로 페이지 관리하기  (0) 2023.03.27