티스토리 뷰

반응형

조상으로부터 Provider를 얻고 해당 값을 builder에 전달합니다.

 

Consumer 위젯은 특별한 작업을 하지 않습니다. 단지 새로운 위젯에서 Provider.of를 호출하고 빌드 구현을 builder에 위임합니다.

 

builder는 null이 될 수 없으며 제공된 값이 변경될 때 여러 번 호출될 수 있습니다.

 

Consumer 위젯의 두 가지 주요 목적은 다음과 같습니다:

  • 해당 제공자의 후손이 아닌 BuildContext를 가지고 있을 때 제공자의 값을 얻을 수 있게 합니다.
  • 더 세밀한 리빌드를 통해 성능을 최적화합니다.

 

 

 

해당 제공자의 후손이 아닌 BuildContext를 가지고 있을 때 제공자의 값을 얻기

이 시나리오는 제공자를 생성하는 위젯이 그 제공자의 소비자이기도 할 때 주로 발생합니다. 예를 들어:

@override
Widget build(BuildContext context) {
  return ChangeNotifierProvider(
    create: (_) => Foo(),
    child: Text(Provider.of<Foo>(context).value),
  );
}

이 예제는 Provider.of가 제공자의 조상인 BuildContext로 호출되기 때문에 ProviderNotFoundException을 발생시킵니다.

 

대신, Consumer 위젯을 사용하면 자체 BuildContext로 Provider.of를 호출할 수 있습니다.

@override
Widget build(BuildContext context) {
  return ChangeNotifierProvider(
    create: (_) => Foo(),
    child: Consumer<Foo>(
      builder: (_, foo, __) => Text(foo.value),
    ),
  );
}

이 코드는 ProviderNotFoundException을 발생시키지 않고 Text를 올바르게 빌드합니다. 또한 foo의 값이 변경될 때마다 Text를 업데이트합니다.

 

 

 

더 세밀한 리빌드를 통해 성능을 최적화하기

listen: false를 Provider.of에 전달되지 않으면, Provider.of에 전달된 BuildContext와 연관된 위젯은 값이 변경될 때마다 리빌드됩니다. 이는 예상된 동작이지만 때로는 더 많은 위젯이 리빌드될 수 있습니다. 예를 들어:

@override
Widget build(BuildContext context) {
  return FooWidget(
    child: BarWidget(
      bar: Provider.of<Bar>(context),
    ),
  );
}

위 코드에서는 BarWidget만 Provider.of로 반환된 값에 의존합니다. 그러나 Bar가 변경되면 BarWidget과 FooWidget 모두 리빌드됩니다.

 

이상적으로는 BarWidget만 리빌드되어야 합니다. 이를 위해 Consumer를 사용할 수 있습니다.

@override
Widget build(BuildContext context) {
  return FooWidget(
    child: Consumer<Bar>(
      builder: (_, bar, __) => BarWidget(bar: bar),
    ),
  );
}

이 상황에서는 Bar가 업데이트될 때 BarWidget만 리빌드됩니다.

 

하지만 FooWidget이 제공자에 의존하고 BarWidget은 제공자에 의존하지 않는 경우는 어떻게 될까요? 예를 들어:

@override
Widget build(BuildContext context) {
  return FooWidget(
    foo: Provider.of<Foo>(context),
    child: BarWidget(),
  );
}

 

Consumer를 사용하여 이 시나리오를 선택적 child 인수를 사용하여 처리할 수 있습니다:

@override
Widget build(BuildContext context) {
  return Consumer<Foo>(
    builder: (_, foo, child) => FooWidget(foo: foo, child: child),
    child: BarWidget(),
  );
}

이 예제에서는 BarWidget이 builder 외부에서 생성됩니다. 그런 다음 BarWidget 인스턴스가 마지막 매개변수로 builder에 전달됩니다.

이는 builder가 새로운 값으로 다시 호출될 때 새로운 BarWidget 인스턴스가 생성되지 않음을 의미합니다. 이를 통해 Flutter는 BarWidget을 리빌드할 필요가 없음을 알게 됩니다. 따라서 이러한 구성에서는 Foo가 변경될 때 FooWidget만 리빌드됩니다.

 

 

 

참고

Consumer 위젯은 MultiProvider 내에서도 사용할 수 있습니다. 이를 위해 builder에 전달된 child를 반환해야 합니다.

MultiProvider(
  providers: [
    Provider(create: (_) => Foo()),
    Consumer<Foo>(
      builder: (context, foo, child) =>
        Provider.value(value: foo.bar, child: child),
    )
  ],
);

참조:

  • Selector: 업데이트를 필터링할 수 있는 Consumer.

 

 

 

생성자

  • Consumer({Key? key, required Widget builder(BuildContext context, T value, Widget? child), Widget? child}) : Provider를 소비합니다.

 

 

 

속성

  • builder → Widget Function(BuildContext context, T value, Widget? child): Provider의 값을 기반으로 위젯 트리를 빌드합니다.
  • hashCode → int: 객체의 해시 코드입니다.
  • key → Key?: 트리에서 하나의 위젯이 다른 위젯으로 교체되는 방식을 제어합니다.
  • runtimeType → Type: 객체의 런타임 유형을 나타냅니다.

 

 

 

메서드

  • build(BuildContext context) → Widget: 이 위젯이 표현하는 사용자 인터페이스의 일부를 설명합니다.
  • buildWithChild(BuildContext context, Widget? child) → Widget: 추가 자식 매개변수를 받는 빌드 메서드입니다.
  • createElement() → SingleChildStatelessElement: 이 위젯의 위치를 관리할 StatelessElement를 생성합니다.
  • debugDescribeChildren() → List: 이 노드의 자식을 설명하는 DiagnosticsNode 객체 목록을 반환합니다.
  • debugFillProperties(DiagnosticPropertiesBuilder properties) → void: 노드와 관련된 추가 속성을 추가합니다.
  • noSuchMethod(Invocation invocation) → dynamic: 존재하지 않는 메서드나 속성에 접근할 때 호출됩니다.
  • toDiagnosticsNode({String? name, DiagnosticsTreeStyle? style}) → DiagnosticsNode: 디버깅 도구와 DiagnosticsNode.toStringDeep에서 사용하는 객체의 디버그 표현을 반환합니다.
  • toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) → String: 이 객체의 문자열 표현입니다.
  • toStringDeep({String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String: 이 노드와 그 자손의 문자열 표현을 반환합니다.
  • toStringShallow({String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) → String: 객체의 한 줄 상세 설명을 반환합니다.
  • toStringShort() → String: 이 위젯의 짧은 텍스트 설명입니다.

 

 

 

연산자

  • operator ==(Object other) → bool: 동등 연산자입니다.
반응형
댓글
공지사항