플러터에서 상태를 쉽게 공유하기 위해서 몇 가지 방법이 있다. 그중에서 Provider를 사용한 상태 관리 방법을 제대로 공부해 볼까 한다. Provider의 공식 문서와 플러터 공식 문서의 상태 관리 문서를 읽고, 나만의 방법으로 정리하였다. 사실 Provider에서도 몇 가지 방법으로 상태 관리를 할 수 있다. 나는 그중에서도 가장 많이 사용되는 ChangeNotifierProvider에 대해서 먼저 정리하려고 한다. ChangeNotifierProvider는 상태가 변경되면 해당 상태를 참고하고 있는 위젯들을 자동으로 리빌드 할 수 있게 만들어 주는 제공자가 된다. 이 문서에서는 플러터의 상태, ChangeNotifierProvider에 대해서 설명하고, 플러터에서 기본으로 제공하는 카운터 앱을 수..
가장 가까운 조상 제공자(ancestor provider)로부터 타입 T의 값을 얻습니다. 이 메서드는 watch의 반대입니다.값이 변경될 때 위젯을 재빌드하지 않으며 StatelessWidget.build와 State.build 내부에서 호출해서는 안 됩니다. 반면, 이러한 메서드 외부에서는 자유롭게 호출할 수 있습니다. 이 기준과 호환되지 않는 경우, Provider.of(context, listen: false)를 사용하는 것을 고려하세요.이 메서드는 동일한 작업을 수행하지만 이러한 추가 제한 사항 없이 사용할 수 있습니다 (하지만 안전하지는 않습니다). [X] 값이 이벤트에만 사용되는 경우 build 내부에서 read를 호출하지 마세요:Widget build(BuildContext context)..
Provider 클래스는 생성(Create) 및 해제(Dispose)를 통해 제공하는 값의 생명주기를 관리하는 Provider입니다. 주로 BLoC와 같은 간단한 작업을 위해 StatefulWidget을 만드는 것을 피하고자 할 때 사용됩니다. Provider는 State.initState와 State.dispose의 조합과 같습니다. Create는 State.initState에서 단 한 번 호출됩니다. InheritedWidget은 값이 생성자 초기화 및 final이어야 하므로 사용할 수 없습니다. 다음 예시는 Model을 한 번 인스턴스화하고 Provider가 트리에서 제거될 때 이를 해제하는 예제입니다:class Model { void dispose() {}}class Stateless exten..
T of(BuildContext context, {bool listen = true,}) 위젯 트리 상에서 가장 가까운 Provider를 얻어 그 값을 반환합니다. 만약 listen이 true이면, 이후 값의 변경이 위젯의 새로운 State.build를 트리거하고, StatefulWidget의 State.didChangeDependencies를 호출합니다. listen: false는 State.initState 내부 또는 provider의 create 메서드 내에서 Provider.of를 호출할 수 있게 하기 위해 필요합니다.Provider( create: (context) { return Model(Provider.of(context, listen: false)); },) 구현static ..
간단한 선언적 상태 관리 시스템의 작동 방식을 보여주는 짧은 애니메이션 gif입니다. Flutter를 탐색하다 보면 화면 간에, 앱 전반에 걸쳐 애플리케이션 상태를 공유해야 할 때가 옵니다. 이를 위해 취할 수 있는 여러 접근 방식이 있으며, 고려해야 할 많은 질문들이 있습니다. 선언형으로 생각하기 시작하세요만약 Android SDK나 iOS UIKit과 같은 명령형 프레임워크에서 Flutter로 넘어왔다면, 앱 개발을 새로운 시각에서 생각해야 합니다.기존에 가지고 있던 많은 가정들이 Flutter에서는 적용되지 않습니다. 예를 들어, Flutter에서는 UI의 일부를 수정하는 대신 처음부터 다시 빌드해도 괜찮습니다. Flutter는 매우 빠르기 때문에, 필요하다면 매 프레임마다 다시 빌드해도 문제가 ..
새 객체 인스턴스 노출하기Providers는 단순히 값을 노출시켜줄 뿐만 아니라, 값의 생성(create), 수신(listen) 그리고 해제(dispose)를 할 수 있도록 합니다. [O] Provider의 create 안에서 신규 객체를 생성하세요.Provider( create: (_) => MyModel(), child: ...) [X] Provider.value에서 객체를 생성하지 마세요. 메모리 누수와 올바른 동작을 하지 않을 수 있습니다.ChangeNotifierProvider.value( value: MyModel(), child: ...) [X] 시간에 따라 변경될 수 있는 변수로 객체를 만들지 마세요.만약 그렇게 생성하였다면, 생성된 객체는 값이 변화해도 업데이트되지 않습니다.int..
변경 사항이 없으면 리빌드를 방지하고 제한된 값만 선택하여 업데이트를 필터링할 수 있습니다. Selector는 Provider.of를 사용하여 값을 얻은 다음 해당 값을 selector에 전달합니다. 그 후 selector 콜백은 빌더를 완료하는 데 필요한 정보만 포함하는 객체를 반환하는 작업을 수행합니다. 기본적으로 Selector는 collection 패키지의 DeepCollectionEquality를 사용하여 selector의 이전 결과와 새로운 결과를 비교하여 builder가 다시 호출되어야 하는지 결정합니다. 이 동작은 커스텀 shouldRebuild 콜백을 전달하여 재정의할 수 있습니다. selector가 리턴하는 값은 불변이어야 하며, 그렇지 않으면 Selector는 변경 사항이 없다고 생각..
조상으로부터 Provider를 얻고 해당 값을 builder에 전달합니다. Consumer 위젯은 특별한 작업을 하지 않습니다. 단지 새로운 위젯에서 Provider.of를 호출하고 빌드 구현을 builder에 위임합니다. builder는 null이 될 수 없으며 제공된 값이 변경될 때 여러 번 호출될 수 있습니다. Consumer 위젯의 두 가지 주요 목적은 다음과 같습니다:해당 제공자의 후손이 아닌 BuildContext를 가지고 있을 때 제공자의 값을 얻을 수 있게 합니다.더 세밀한 리빌드를 통해 성능을 최적화합니다. 해당 제공자의 후손이 아닌 BuildContext를 가지고 있을 때 제공자의 값을 얻기이 시나리오는 제공자를 생성하는 위젯이 그 제공자의 소비자이기도 할 때 주로 발생합니다. 예를..