flutter는 UI를 변경하려면 다시 빌드를 해야한다. 위젯을 변경하기 위해 외부에서 메소드를 호출하는 방식은 어려우며, 추천하지 않는 방식이다.
여러 위젯에서 app state를 수정해야 하면 많은 callback pass가 필요하다.
다행스럽게도 플러터에서는 자손들에게 데이터와 서비스를 제공하는 InheritedWidget
,InheritedNotifier
,InheritedModel
등과 같은 메커니즘이 존재한다.
flutter에서는 위의 메커니즘들보다 더 높은 수준의 사용하기 쉬운 패키지로 Provider
를 제공하고 있다.
provider는 크게 생성 부분과 소비 부분으로 나뉜다.
상태 관리를 목적으로 하고 있으며 , UI와 비즈니스 로직을 분리하는 목적이다.
생성 부분에서는 사용할 데이터 타입을 결정하고 해당 데이터에 대한 Provider를 만들고, 소비 부분에서는 Provider를 통해 데이터를 불러오거나 수정하는 등의 작업을 진행한다. (Provider의 데이터 값을 변경하거나 화면에 보여주는 것을 의미)
구현하고자 하는 기능, class를 만들고 이에 대한 provider를 생성한다. 숫자를 세는 counter class를 만들었다고 치면 숫자가 변동되었더라도 바로 UI에 반영되지 않기 때문에 UI에 반영시켜주는 ChangeNotifierProvider 를 사용해야 한다. (flutter 기본 sdk class)
ChangeNotifier
는 app state를 encapsulate하는 하나의 방식으로, 내부 변화를 인스턴스들에게 전달하는 역할이다.
ChangeNotifierProvider
는 자손들에게 ChangeNotifier 인스턴스를 제공한다.
Consumer
를 이용해서 Provider의 데이터를 사용할 수 있다.
pubspec.yaml에 provider package를 적어둬야 한다.
flutter pub add provider
그리고 provider를 사용하려는 코드파일의 상단에 import문을 적는다.
import 'package:provider/provider.dart';
ChangeNotifierProvider 인스턴스를 통해 사용한다. main.dart를 분리해서 코드 작성한다.
context.watch<T>()
, context.read<T>()
를 통해 Provider의 데이터를 사용할 수 있다.
이 둘은 비슷하지만 분명한 차이점이 존재한다.
context.watch<T>()
는 T
의 데이터 값이 변경되었을 때 위젯을 재빌드.
context.read<T>()
는 T
의 데이터 값이 변경되었을 때 위젯을 재빌드하지 않는다.
context.watch<T>()
는 Provider.of<T>(context)
와 동일하고, context.read<T>()
는 Provider.of<T>(context, listen: false)
와 동일하다. 택 1 해서 사용하면 된다.
위의 방법을 사용하지 못하고, consumer
를 사용해야 한다.