Flutter/Riverpod

Flutter) Riverpod "ref" 얻기 - 3

주톨 2023. 1. 21. 12:25
728x90

이 글은 Riverpod 공식문서를 참조했습니다.

 

 

이 글에서는 "ref" 객체를 얻는 방법을 설명하겠습니다.

 

"ref" 객체 얻기

 

프로바이더를 읽기전에 "ref" 객체를 얻어야 합니다.

"ref"는 프로바이더간에 상호작용을 도와주고 위젯이나 다른 프로바이더에서 얻을 수 있습니다.

 

 

프로바이더로 부터 "ref" 객체 얻기

모든 프로바이더는 "ref" 객체를 파라미터로 받게 됩니다.

final provider = Provider((ref) {
  // 다른 프로바이더 객체를 얻기위해 ref를 사용합니다. 
  // 여기서 repositoryProvider 프로바이더를 Provider 에서 읽는 것을 확인합니다.
  final repository = ref.watch(repositoryProvider);

  return SomeValue(repository);
})

 

 

final counterProvider = StateNotifierProvider<Counter, int>((ref) {
  return Counter(ref);
});

class Counter extends StateNotifier<int> {
  Counter(this.ref) : super(0);

  final Ref ref;

  void increment() {
    // Counter 클래스는 다른 프로바이더를 읽기 위해 "ref"를 사용할 수 있습니다.
    final repository = ref.read(repositoryProvider);
    repository.post('...');
  }
}

 

 

 

위젯에서 "ref" 객체 얻기

위젯들은 "ref" 파라미터를 가지고 있지 않습니다.

그러나 Riverpod에서는 위젯에서 "ref" 객체를 얻기위한 솔루션을 제공합니다.

 

기본적으로 위젯을 생성할 때 상속받는 StatelessWidget 대신 ConsumerWidget으로 상속받기
가장 기본적으로 위젯에서 "ref" 객체를 얻기위한 방법입니다.

 

ConsumerWidget은 기본적으로 StatelessWidget 과 동일합니다.

차이가 있다면 build메소드에 추가적으로 "ref" 객체를 받습니다.

 

-StatelessWidget 

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Riverpod Study")),
        body: Center(child: Text("Hello world")),
      ),
    );
  }
}

 

-ConsumerWidget

class MyApp extends ConsumerWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    //ref를 사용해 프로바이더 구독하기
    final String value = ref.watch(helloWorldProvider);

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Riverpod Study")),
        body: Center(child: Text(value)),
      ),
    );
  }
}

 

 

기존 Riverpod
StatelessWidget ConsumerWidget
StatefulWidget + State ConsumerStatefulWidget + ConsumerState

차이점은 "ref" 객체를 상태로 가지는 점 입니다.

 

 

 

StatefulWidget을 ConsumerStatefulWidget으로 변경

 

-StatefulWidget 

class HomeViewState extends StatefulWidget {
  const HomeViewState({Key? key}) : super(key: key);

  @override
  State<HomeViewState> createState() => _HomeViewStateState();
}

class _HomeViewStateState extends State<HomeViewState> {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

-ConsumerStatefulWidget 변경

class HomeView extends ConsumerStatefulWidget {
  const HomeView({Key? key}) : super(key: key);

  @override
  HomeViewState createState() => HomeViewState();
}

class HomeViewState extends ConsumerState<HomeView> {
  @override
  void initState() {
    super.initState();
    // "ref"는 StatefulWidget의 모든 생명주기 상에서 사용할 수 있습니다.
    ref.read(counterProvider);
  }

  @override
  Widget build(BuildContext context) {
    // "ref"는 build 메소드 안에서 프로바이더를 구독(listen)하기위해 사용할 수 있습니다.
    final counter = ref.watch(counterProvider);
    return Text('$counter');
  }
}

ConsumerWidget 과의 차이점은 build 메소드에 ref객체를 전달하지 않습니다.

ConsumerState 객체에 "ref"객체가 포함됩니다.