관리 메뉴

Bull

[Flutter::State] RiverPod Tutorial - Getting Started Review 본문

Software Framework/Flutter

[Flutter::State] RiverPod Tutorial - Getting Started Review

Bull_ 2024. 10. 28. 10:01

패키지 설치

flutter pub add flutter_riverpod
flutter pub add riverpod_annotation
flutter pub add dev:riverpod_generator
flutter pub add dev:build_runner
flutter pub add dev:custom_lint
flutter pub add dev:riverpod_lint

핵심만 짚어보자면,

annotaion은 리버팟을 @ (어노테이션)을 통해 코드를 수월하게 관리할 수 있도록 해준다. (쉽게 보자면 생성기 역할을 해주는 것)
@riverpod은 리버팟에서 제공하는 애너테이션 기반 프로바이더 생성 방식으로, 이를 통해 수동 코드 작성 없이 프로바이더를 자동으로 생성할 수 있다.

 

build_runner는 코드 중에 @를 파싱 후 코드를 직접 생성해주도록 돕는다.
예를 들어 @riverpod 을 보고 provider를 만들어 줌.

 

riverpod_lint는 리버팟 관련 코드의 문법적 오류와 스타일을 체크하여 잘못된 사용을 방지하도록 도와준다.

 

2024-10-28 기준 yaml에 적용된 패키지 버전

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.6
  flutter_riverpod: ^2.6.1
  riverpod_annotation: ^2.6.1

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^3.0.0
  riverpod_generator: ^2.4.0
  build_runner: ^2.4.11
  custom_lint: ^0.6.4
  riverpod_lint: ^2.3.10

lint 적용

lint를 적용하려면, analysis_options.yaml에 다음 프로퍼티를 추가한다.
이는 riverpod_lint 패키지가 해당 파일을 보고 설정을 도와준다.

analyzer:
  plugins:
    - custom_lint

Example: hello world

튜토리얼에 나오는 코드다.

몇 부분만 살펴보자.


import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'main.g.dart';

// We create a "provider", which will store a value (here "Hello world").
// By using a provider, this allows us to mock/override the value exposed.
@riverpod
String helloWorld(Ref ref) {
  return 'Hello world';
}

void main() {
  runApp(
    // For widgets to be able to read providers, we need to wrap the entire
    // application in a "ProviderScope" widget.
    // This is where the state of our providers will be stored.
    ProviderScope(
      child: MyApp(),
    ),
  );
}

// Extend ConsumerWidget instead of StatelessWidget, which is exposed by Riverpod
class MyApp extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final String value = ref.watch(helloWorldProvider);

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Example')),
        body: Center(
          child: Text(value),
        ),
      ),
    );
  }
}

part 'main.g.dart'; 를 보자마자 뭔가 싶었다. main.g.dart 파일을 포함한다는 의미인데, 오류 표시가 뜬다. 그래서 튜토리얼 윗부분을 자세히 보니 dart run build_runner watch 라는 명령어가 있었다.

 

build_runner는 우리가 설치한 패키지인데 코드 생성을 도와준다. 정확히 @riverpod 을 보고 main.g.dart에 프로바이더를 생성해준다.

watch는 구독을 실시간하여 내가 main.dart 파일을 확인하는 순간 어노테이션을 보고 해당 파일을 생성한다. 하지만 한번에 하려면 다음 명령어를 사용해도 좋다.

 

flutter pub run build_runner build

생성된 main.g.dart 파일을 아래처럼 프로파이더 코드가 등록된다.

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'main.dart';

// **************************************************************************
// RiverpodGenerator
// **************************************************************************

String _$helloWorldHash() => r'9abaa5ab530c55186861f2debdaa218aceacb7eb';

/// See also [helloWorld].
@ProviderFor(helloWorld)
final helloWorldProvider = AutoDisposeProvider<String>.internal(
  helloWorld,
  name: r'helloWorldProvider',
  debugGetCreateSourceHash:
      const bool.fromEnvironment('dart.vm.product') ? null : _$helloWorldHash,
  dependencies: null,
  allTransitiveDependencies: null,
);

typedef HelloWorldRef = AutoDisposeProviderRef<String>;
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

이제 main에서는 이 파일을 임포트한 것과 같이 부분으로 포함되기 때문에 프로파이더를 직접 사용할 수 있다.

@riverpod을 사용하면 ---Provider 로 접미사를 붙여서 사용하면 되는 것 같다.

 

이제 Myapp 위젯 클래스를 보면
final String value = ref.watch(helloWorldProvider); 로 프로바이더가 구독되도록 초기화하는 것을 확인할 수 있다.

 

그 이외에는 riverpod의 기본 문법들이 적용된 몇 가지가 존재한다.

 

ProviderScope : app이 실행될 때 앱 전체에 리버팟 프로바이더 상태를 저장하고 공유할 수 있도록 하는 상위 컨테이너다.

 

ConsumerWidget : StatefulWidget 대신 rivderpod에서 사용하는 상속 클래스이고 리버팟에서 프로바이더 상태를 구독하고, UI를 해당 상태에 따라 업데이트할 수 있는 위젯이다.

 

WidgetRef : ConsumerWidget의 build 메서드에서 제공되는 객체로, 프로바이더의 상태를 참조할 수 있도록 해준다.