Flutter 제공 업체 모두 이해하기

Pixabay로부터 입수 된 ErikaWittlieb 님의 사진입니다.

공식 Flutter 사이트 ( Simple 앱 상태 관리 )에서는 Provider 패키지가 "이해하기 쉽다"고 말했지만 항상 그런 것은 아닙니다. 주된 원인은 다음과 같은 공급자 유형의 수입니다.

  • 공급자
  • ListenableProvider
  • ChangeNotifierProvider
  • ValueListenableProvider
  • StreamProvider
  • FutureProvider
  • 다중 제공자
  • ProxyProvider
  • ChangeNotifierProxyProvider
  • 그리고 더

이 문서의 목적은 각 주요 공급자 유형의 용도를 이해하는 데 도움이됩니다. 나는 각각이 어떻게 사용되는지에 대한 최소한의 예를 제공 할 것입니다. 그런 다음 차이점을 이해하면 Provider 패키지를 사용하여 프로젝트에서 앱 상태를 관리할지 여부와 방법을 직접 결정할 수 있습니다.

설정

아래 예제에서 다음 레이아웃을 사용하겠습니다.

이것이 의미입니다.

  • "Do something"버튼은 앱 상태를 변경하는 모든 앱 이벤트를 나타냅니다.
  • "Show something"텍스트 위젯은 앱 상태를 표시해야하는 UI의 모든 부분을 나타냅니다.
  • 왼쪽의 녹색 사각형과 오른쪽의 파란색 사각형은 위젯 트리의 서로 다른 두 부분을 나타냅니다. 업데이트되는 이벤트와 UI가 앱의 어느 부분 에나있을 수 있음을 강조하기 위해 존재합니다.

또한 아래 예에서는 pubspec.yaml 파일 에 provider 패키지 가 이미 있다고 가정 합니다.

dependencies:
  provider: ^4.0.1

import 'package:provider/provider.dart';

상상할 수 있듯이, Provider가장 기본적인 Provider 위젯 유형입니다. 이를 사용하여 위젯 트리의 아무 곳에 나 값 (일반적으로 데이터 모델 개체)을 제공 할 수 있습니다. 그러나 값이 변경되면 위젯 트리를 업데이트하는 데 도움이되지 않습니다.

앱 상태가 다음과 같은 모델이라고 가정합니다.

class MyModel { 
  String someValue = 'Hello';
void doSomething() {
    someValue = 'Goodbye';
    print(someValue);
  }
}

아래 코드에서 Provider및 두 개의 Consumer위젯을 찾습니다 .

이를 실행하면 다음과 같은 결과가 나타납니다.

메모:

  • UI는 모델에서 가져온 "Hello"텍스트로 빌드되었습니다.
  • "Do something"버튼을 누르면 모델에서 이벤트가 발생합니다. 그러나 모델의 데이터가 변경 되었더라도 Provider위젯이 제공하는 값의 변경을 수신하지 않기 때문에 UI가 다시 빌드 되지 않았습니다.

기본 Provider위젯 과 달리 ChangeNotifierProvider모델 개체의 변경 사항을 수신합니다. 변경 사항이 있으면 Consumer.

코드에서 변경 ProviderChangeNotifierProvider. 모델 클래스는 ChangeNotifier 믹스 인 을 사용 하거나 확장해야합니다. 이렇게하면에 액세스 할 수 notifyListeners()있으며 호출 할 때마다에 ChangeNotifierProvider알림이 전송되고 소비자는 위젯을 다시 빌드합니다.

다음은 완전한 코드입니다.

이제 "Do something"버튼을 누르면 텍스트가 "Hello"에서 "Goodbye"로 변경됩니다.

메모:

  • 대부분의 앱에서 모델 클래스는 자체 파일에 있으며 .NET flutter/foundation.dartFramework를 사용 하려면 가져와야 합니다 ChangeNotifier. 그것은 당신의 비즈니스 로직이 이제 프레임 워크에 의존 하고 프레임 워크가 세부 사항 이라는 것을 의미하기 때문에 저는 그 팬이 아닙니다 . 하지만 지금은 기꺼이 함께 살 것입니다.
  • Consumer때마다 위젯은 아래에있는 위젯을 재 구축 notifyListeners()불려갑니다. 버튼을 업데이트 할 필요는 없으므로를 사용하는 대신 리스너를 Consumer사용 Provider.of하고 false로 설정할 수 있습니다 . 이렇게하면 변경 사항이있을 때 버튼이 다시 작성되지 않습니다. 다음은 자체 위젯으로 추출 된 버튼입니다.
  • class MyButton extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
    final myModel = Provider.of<MyModel>(context, listen: false);
    return RaisedButton(
          child: Text('Do something'),
          onPressed: () {
            myModel.doSomething();
          },
        );
      }
    }
    

FutureProvider 기본적으로FutureBuilder위젯. UI에 표시 할 초기 데이터를 제공하고 제공하려는 가치의 미래도 제공합니다. FutureProvider미래의 완료는 다음 소비자에게 통지 자신의 위젯을 재건 할 때 수신합니다.

아래 코드에서 빈 모델을 사용하여 UI에 초기 데이터를 제공했습니다. 3 초 후에 새 모델을 반환하는 기능도 추가했습니다. 이것이 FutureProvider기다리는 것입니다.

기본과 마찬가지로 Provider, FutureProvider모델 자체 내에서 변경을 수신하지 않습니다. 아래 코드에서 "Do something"버튼으로 2 초 후에 모델을 변경하는 것을 보여줍니다. UI에는 영향이 없습니다.

다음은 전체 코드입니다.

메모:

  • 은 완료 후 다시 빌드하도록 FutureProvider지시합니다 .ConsumerFuture<MyModel>
  • 핫 재시작을 눌러 초기 값으로 앱을 다시 빌드하십시오.
  • Future가 완료된 후에도 "Do something"버튼을 눌러도 UI가 업데이트되지 않습니다. 그런 종류의 기능을 원한다면 ChangeNotifierProvider마지막 섹션 의 를 사용 하십시오.
  • 에 대한 사용 사례 FutureProvider는 파일 또는 네트워크에서 일부 데이터를 읽는 것입니다. 하지만 FutureBuilder. 나의 비전문가 의견으로 FutureProviderFutureBuilder. 공급자가 필요하면을 사용 ChangeNotifierProvider하고 공급자가 필요하지 않으면 FutureBuilder. 그래도 댓글을 추가하고 싶으시면 업데이트 해 드리겠습니다.

StreamProvider기본적으로 StreamBuilder. 스트림을 제공 한 다음 스트림에 이벤트가있을 때 소비자가 다시 빌드됩니다. 설정은 FutureProvider위와 매우 유사합니다 .

스트림에서 내 보낸 값을 변경할 수없는 것으로 간주해야합니다. 즉 StreamProvider, 모델 자체의 변경 사항을 듣지 않습니다. 스트림의 새 이벤트 만 수신합니다.

아래 코드 StreamProvider는 모델 객체의 스트림을 제공 하는를 보여줍니다 . 다음은 전체 코드입니다.

메모:

  • StreamProvider알려줍니다 Consumer새로운 스트림 이벤트가있을 때 후 다시.
  • 핫 재시작을 눌러 초기 값으로 앱을 다시 빌드하십시오.
  • "Do something"버튼을 눌러도 UI가 업데이트되지 않습니다. 그런 종류의 기능을 원한다면 ChangeNotifierProvider. 사실, 모델 객체에 스트림이 있고 notifyListeners(). StreamProvider이 경우에는 전혀 필요하지 않습니다 .
  • 를 사용 StreamProvider하여 BLoC 패턴을 구현할 수 있습니다 .

이 항목을 지나서 자유롭게 스크롤하십시오. 마치 ChangeNotifierProvider. . . 그러나 더 복잡합니다. . . 그리고 명백한 부가가치없이.

당신이있는 경우 ValueNotifier이 등을

class MyModel {
ValueNotifier<String> someValue = ValueNotifier('Hello');
void doSomething() {
    someValue.value = 'Goodbye';
  }
}

다음은 전체 코드입니다.

메모:

  • "Do something"버튼을 누르면 "Hello"가 "Goodbye"로 변경됩니다 ValueListenableProvider.
  • 위젯 트리의 맨 위에 Provider.of<MyModel>(context, listen: false)있는 것보다을 사용하는 것이 더 낫습니다 Consumer. 그렇지 않으면 매번 전체 트리를 재건합니다.
  • Provider<MyModel>및 "Do something"버튼 클로저 myModel모두에 제공 됩니다 ValueListenableProvider.
  • Consumer<String>에 대한 Text위젯에서 값을 얻기 위해 알고 ValueListenableProvider<String>때문에 String유형이 일치.
  • 진지하게,이 예제를 만드는 것은 고통 스러웠습니다. 특히 Consumer위젯 트리의 맨 위에 를 삽입하고 모든 괄호와 괄호를 섞으려고했습니다. 그러나 MultiProvider(아래 참조)를 사용하면 개선되었을 것입니다. 또는 약간의 고통을 덜어주고 ChangeNotifierProvider.

ListenableProvider

자신 만의 특별한 공급자를 구축해야하는 경우에만 이것을 사용합니다. 문서 조차도 당신이 아마도 ChangeNotifierProvider대신 원한다고 말합니다 . 따라서 ListenableProvider좋은 사용 사례를 찾으면 나중에이 섹션을 업데이트 할 수 있지만 지금 은 무시 하겠습니다.

다중 제공자

지금까지 예제에서는 하나의 모델 객체 만 사용했습니다. 두 번째 유형의 모델 개체를 제공해야하는 경우 공급자를 중첩 할 수 있습니다 ( ValueListenableProvider위 예제에서 수행 한 작업 과 유사 ). 그러나 모든 중첩은 지저분합니다. 이를위한 깔끔한 방법은 MultiProvider.

다음 예에는 두 개의 ChangeNotifierProviders.

다음은 전체 코드입니다. 조금 깁니다. 아래로 스크롤 하여 하단 MultiProviderConsumers,, 및 두 모델 클래스를 확인하십시오.

메모:

  • 첫 번째 "Do something"버튼을 누르면 "Hello"가 "Goodbye"로 변경됩니다. 두 번째 "Do something"버튼을 누르면 "0"이 "5"로 변경됩니다.
  • 이것과 싱글 사이에는 크게 다르지 않습니다 ChangeNotifierProvider. 서로 다른 소비자가 올바른 모델을 얻는 방법은 그들이 나타내는 유형에 따라 다릅니다. 즉, Consumer<MyModel>gets MyModel, Consumer<AnotherModel>gets AnotherModel.

제공하려는 모델이 두 개 있지만 모델 중 하나가 다른 모델에 의존하는 경우 어떻게해야합니까? 이 경우 ProxyProvider. A ProxyProvider는 한 공급자의 값을 가져 와서 다른 공급자에 주입 할 수 있도록합니다.

a를 설정하는 방법이 ProxyProvider처음에는 혼란 스러울 수 있으므로 이에 대해 약간의 설명을 추가하겠습니다.

기본 ProxyProvider은 꺾쇠 괄호에 두 가지 유형이 있습니다. 첫 번째 유형은 두 번째 유형이 의존하는 것입니다. 즉, 다른 .NET에서 이미 제공 한 모델입니다 Provider. update클로저 의 두 번째 모델 유형에 주입됩니다 . 세 번째 매개 변수 ( anotherModel)는 이전에 빌드 된 값을 저장하지만 여기서는 사용하지 않습니다. 우리 myModelAnotherModel.

예제의 전체 코드는 다음과 같습니다.

메모:

  • 텍스트는 "Hello"로 시작합니다.
  • "Do something"버튼을 누르면 MyModel텍스트가 "Goodbye"로 변경됩니다. MyModel리스너 ( ChangeNotifierProvider)에 알리고 UI가 새 텍스트로 다시 빌드됩니다.
  • "다른 작업 수행"단추를 누르면에서 주입 된 내용을 AnotherModel가져 와서 텍스트를 "나중에 보자"로 변경합니다. 리스너에게 변경 사항을 알리기 때문에 UI가 다시 업데이트됩니다. 변경된 자체 데이터가있는 경우 변경 사항을 수신하지 않기 때문에 UI가 업데이트 되지 않습니다. 당신은 그것을 위해 필요할 것 입니다.MyModelProxyProviderMyModelAnotherModelProxyProviderChangeNotifierProxyProvider
  • ProxyProvider나를 위해 충분히 혼란 스러웠습니다. ChangeNotifierProxyProvider더 특별한 경고와 경고가 있습니다. 따라서 지금은 이에 대한 예제를 추가하지 않을 것입니다. 그래도 문서를 확인할 수 있습니다 .
  • FilledStacks 와 동의 하여 GetIt 패키지ProxyProvider.

결론을 내리기 전에 Provider 사용법을 배우면서 혼란 스러웠던 한 가지 더 설명하고 싶습니다.

공급자 위젯의 대부분 (모두는 아니지만)에는 두 가지 종류의 생성자가 있습니다. 기본 생성자는 create모델 개체를 만드는 함수를 사용합니다. 위의 대부분의 예에서 그렇게했습니다.

Provider<MyModel>(
  create: (context) => MyModel(),
  child: ...
)

객체가 이미 생성되었고 그에 대한 참조 만 제공하려는 경우 다음과 같은 명명 된 생성자를 사용할 수 있습니다 value.

final myModel = MyModel();
...
Provider<MyModel>.value(
    value: myModel, 
    child: ...
)

결론

이 모든 것이 끝나면 Provider 패키지의 대부분의 클래스를 무시할 수 있습니다. 사용 방법 ChangeNotifierProviderConsumer. 때때로 ProviderUI를 업데이트 할 필요가없는 경우 위젯을 사용할 수 있습니다 . Futures 및 Streams에 대한 논리는 모두를 알리는 모델 클래스에 넣을 수 있습니다 ChangeNotifierProvider. FutureProvider또는에 대한 필요가 없습니다 StreamProvider. 대부분의 MultiProvider경우 각 화면 또는 페이지에 대한보기 모델이있는 경우 둘 중 하나 가 필요하지 않습니다 . 뷰 모델에 종속성을 삽입하기 위해 GetIt이이를 처리합니다. 걱정할 필요가 없습니다 ProxyProvider. 이 게시물 은 내가 여기서 설명한 내용에 대한 매우 구체적인 도움을 제공합니다.

대부분의 Provider 패키지를 무시하라고 말하고 있지만 핵심은 좋아합니다. 에 초점을 맞추면 ChangeNotifierProvider앱 상태와 아키텍처를 쉽게 처리 할 수 ​​있습니다.

다음 단계 : Riverpod

Riverpod 에 대해 들어 보셨을 것 입니다 . Provider를 기반으로 구축되었으며 동일한 작성자가 작성한 상태 관리 솔루션입니다. 하지만 공급자가 제공 한 모든 옵션에 대해 혼란 스러웠다면 Riverpod는 더 많은 것을 제공합니다. 그러나 옵션을 살펴볼 수 있다면 Riverpod는 많은 일을 더 쉽게 만듭니다. 나는 당신이 그것을 시도하는 것이 좋습니다.

Riverpod 프로젝트를 설정하는 과정을 안내하는 튜토리얼을 작성했습니다. 모든 선택이 단순화되어 단계별로 따라갈 수 있습니다. 여기 링크가 있습니다:

Flutter Riverpod 튜토리얼 : 카운터 앱

감사

Provider에 대한 다양한 설명과 튜토리얼을 많이 읽었지만 다음 소스에서 영감을 받아 특별히 감사드립니다.

Suggested posts

좋은 습관을 만들고 유지하는 방법

장기적인 습관을 유지하기위한 생산성 팁

좋은 습관을 만들고 유지하는 방법

두 아이의 엄마가 된 후 일을 끝내기가 더 어려워졌습니다. 나는 한 작업에서 다음 작업으로 뛰어 들었고 하루가 끝날 때까지 아무것도하지 않았을 때 실망했습니다.

양자 컴퓨팅 Pt를위한 프로그래밍. 1 : NumPy

이제 양자 컴퓨팅이면의 물리학을 배우기 시작 했으므로 "이봐, 실제로 양자 컴퓨터를 사용하려면 실제로 양자 장치를 손으로 만들어야합니까?"라고 궁금해 할 것입니다. 답은 양자 컴퓨터를 컴퓨터라고 부르는 이유가 있습니다. 프로그래밍이 가능합니다! 이 시리즈에서는 수학 개념을 시뮬레이션하고 양자 컴퓨터에서 실행하는 소프트웨어를 구축하는 방법을 배우게됩니다. 깨끗하고 현대적이며 라이브러리가 풍부한 언어이기 때문에 Python을 사용하여 코드를 작성할 것입니다.