[flutter] Provider: 앱에서 상태관리하기

KoEunseo·2023년 11월 27일
0

flutter

목록 보기
40/45

프로바이더

플러터에 특화되어있고, 상태관리 툴을 제공한다.
프로바이더는 위젯이다.

Provider({
  Key? key,
  required Create<T> create,
  Dispose<T>? dispose,
  bool? Lazy,
  TransitionBuilder? builder,
  Widget? child
});
  • 프로바이더가 필요한 위젯들의 상위에 위치해야 한다.
  • Create가 꼭 제공되어야한다.

간단한 예시

return Provider<Dog>(
  create: (context) => Dog(name: 'seolgi', breed: 'pomeranian', age: 5),
  child: MaterialApp(... 생략)
)

// 자손위젯
return Scaffold(
  body: Text('name: ${Provider.of<Dog>(context).name}')
)

provider의 of라는 메서드에게 타입을 제공하고, context를 탐색해 해당 인스턴스의 속성 'name'을 리턴한다.
이때 해당 타입이 중복된다면(Dog 타입 인스턴스가 여러개라면) 위젯 트리 상에서 가장 가까운 곳에 위치한 인스턴스를 리턴한다.

ChangeNotifier

Dog 인스턴스 내에서 age를 증가시키는 메서드를 추가했다.
그러나 setState와 같은 어떤 알람이 필요해 보인다.
콘솔로 찍어보면 값은 분명 바뀌고있으나 화면에는 반영되지 않고 있다.
이때 프로바이더에서 사용하는 것이 ChangeNotifier이다.
Dog 클래스와 ChangeNotifier를 Mixin한다.

(mixin은 sass에서 해본 건데... extends하는 게 아니라 mixin인 이유가 뭘까? override하지 않게 하기 위함일까?)

class Dog with ChangeNotifier { //추가
  final String name;
  Dog({
    required name;
  })
  void grow() {
    age++;
    notifyListners(); //추가
  }
}

addListner

가장 상위 컴포넌트의 Provider를(머터리얼 앱을 감싸고 있던) 삭제한다.
생성했던 dog 인스턴스 또한 삭제한다.

그리고 바로 아래 위젯을 statefulwidget으로 바꾼다.
그리고 dog 인스턴스를 새로 하나 생성한다.
dog.addListener에 grow가 실행될때마다 실행 될 콜백함수를 등록한다.
그리고 dog.removeListener로 dispoise해준다.

이때 프로바이더가 삭제되었으니 dog를 자손 위젯에 직접 전달해주어야한다... 이게 맞나?

changeNotifierProvider

머터리얼 앱을 ChangeNotifierProvider로 감싸준다.
그리고 create 속성을 이용해 Dog를 생성한다.

return ChangeNotifierProvider<Dog>(
  create: (context) => Dog(name: 'seolgi', breed: 'pomeranian', age: 5),
  child: MaterialApp(... 생략)
)

위 단계에서 생성했던 Dog 삭제, init, dispose 삭제.
Provider가 다시 생성되었으니 Provider.of를 통해 필요한 데이터 제공.
Provider.of<Dog>(context, listen: false).grow(), listen을 false로 주어야 에러가 사라진다.

extension methods

read

Provider.of<T>(context, listen: false)와 같다.

watch

Provider.of<T>(context)와 같다. 상태를 구독한다.

select

context.select<Dog, String>((Dog dog) => dog.name) 선별적으로 특정 값만 구독한다.

profile
주니어 플러터 개발자의 고군분투기

0개의 댓글