Provider로 상태 관리하기
포스트
취소

Provider로 상태 관리하기

Provider란?

  • 상태 값 관리를 위한 패키지
  • 위젯 트리에서 거리가 멀리 있는 위젯끼리 같은 데이터가 필요할 때
    상태를 공유하는 공통된 부모 위젯을 Stateful 위젯으로 만들고
    자식 위젯을 새엉할 때 파라미터로 해당 상태를 전달하면
    두 위젯 사이에서 동일한 상태를 사용할 수 있다.
    • 그러나 불필요한 위젯들이 리빌드되면서 성능 이슈가 나타날 수 있다.
    • Provider는 불필요한 리빌드로 인한 성능 이슈 하락을 방지하기 위해 만들어졌다.
  • 참고

Provider의 특징

  • 위젯 트리와 상관없이 상태(데이터)를 저장할 클래스를 생성해서 사용한다.
  • 해당 상태를 공유하는 공통 부모 위젯에 Provider를 제공한다.
  • 해당 상태를 사용하는 곳에서는 Provider의 데이터를 읽어서 사용한다.
  • Provider의 상태 클래스에 있는 필드에 값 변화가 일어나면
    해당 필드가 포함된 위젯 트리 전체가 아닌
    해당 필드가 사용된 위젯 자체만 리빌드딘다.

pubspec.yaml

provider: ^6.1.1

Provider 생성 방법

import 'package:provider/provider.dart';

class Provider extends ChangeNotifier {
    필드_목록...
    메소드_목록...
}

Provider 선언 방법 (main.dart)

  • 기존
void main() {
  runApp(MyApp());
}
  • 변경
runApp(MultiProvider(
    providers: [
      ChangeNotifierProvider(create: (_) => Provider_클래스명_1()),
      ChangeNotifierProvider(create: (_) => Provider_클래스명_2()),
      ChangeNotifierProvider(create: (_) => Provider_클래스명_3()),
      ...
    ],
    child: MyApp(),
  ));

Provider 사용 방법 1

//Provider 생성
class ExampleProvider extends ChangeNotifier {
    String title = "기존 이름";
}

//State 쪽에서 선언
var exampleProvider = Provider.of<ExampleProvider>(Globals.navigatorKey.currentContext!, listen: false); //전역에서 사용할 수 있는 GlobalKey<NavigatorState>() 사용

//실제 사용
Container(
    child: Center(
        child: Text(exampleProvider.title)
    )
)

//데이터 갱신
exampleProvider.title = "신규 이름";
exampleProvider.notifyListeners();

Provider 사용 방법 2

//Provider 생성
class ExampleProvider extends ChangeNotifier {
    String title = "기존 이름";
}

//필드를 사용할 위젯의 부모 위젯으로 Consumer<T> 선언
//{required Widget Function(BuildContext, T, Widget?) builder}
Consumer<ExampleProvider>(builder: (context, exampleProvider, child) {
    return Column(
        children: [
            Text(exampleProvider.title),
            OutlinedButton(onPressed: (){
                exampleProvider.title = "신규 이름";
                exampleProvider.notifyListeners();
            }, child: Text("이름 변경")),
        ]
    );
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.