Flutter

[Flutter] Riverpod 사용법, 간단 예제, riverpod generator

izongg 2024. 8. 25. 15:49
반응형

Riverpod을 사용하여 개발할 때 StateProvider나 StateNotifierProvider 등을 직접 작성하지 않고,

riverpod_annotation을 통해 코드를 생성하는 방법이다.

 

공부할때는 StateProvider나 StateNotifierProvider을 작성하는 방법으로 공부하였지만, 실제 프로젝트에서 사용할때는 code generation을 통해 작업을 하였다.

 

사용 패키지

flutter_riverpod: ^2.4.9
riverpod_annotation: 2.3.3
riverpod_generator: 2.3.9
build_runner: 2.3.3

 

flutter pub add flutter_riverpod &&
flutter pub add riverpod_annotation &&
flutter pub add riverpod_generator &&
flutter pub add build_runner

 

예제코드

폴더 구조는 다음과 같이 하였다.

 

main.dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_exam/view/count_view.dart';

void main() {
  runApp(const MainApp());
}

class MainApp extends StatelessWidget {
  const MainApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const ProviderScope(
      child: MaterialApp(
        home: Scaffold(
          body: CountView(),
        ),
      ),
    );
  }
}

 

해당 앱의 최상단인 main.dart파일의 MaterialApp을 ProviderScope로 감싸준다.

이는 앱의 상태를 관리할 수 있는 범위를 지정해주는 것이다.

count_provider.dart

import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'count_provider.g.dart'; // 생성할 파일이름, 해당파일이름.g.dart

@riverpod
class CountProvider extends _$CountProvider {

  @override
  Future<int> build() async {
    return 0;
  }
  
}

 

provider 파일은 이렇게 작성해준다.

class 위에 @riverpod 을 꼭 붙이고, part에는 해당파일이름.g.dart 로 작성해준다.

build에서는 상태관리를 할 변수 타입을 return해주도록 한다.

 

현재는 code generate를 하지않았기 때문에 에러가 난다. 코드 생성을 하기위해

flutter pub run build_runner build --delete-conflicting-outputs

를 터미널에 입력한다.

 

그러면 이렇게 count_provider.g.dart 파일이 생성된다.

 

count_view.dart

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

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

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return const Placeholder();
  }
}

 

view 파일에선 extends로 ConsumerWidget으로 하고,

build에 WidgetRef ref를 추가하여 사용한다.

 

 

이러면 기초 세팅 끝이다. 이제 카운트를 보여주는 위젯을 만들고, 실제로 상태를 변경시키는 기능을 사용해보겠다.

 

count_provider.dart

import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'count_provider.g.dart';

@riverpod
class CountProvider extends _$CountProvider {
  @override
  Future<int> build() async {
    return 0;
  }

  countUp() {
    update((count) async {
      count++;
      return count;
    });
  }

}

countUp함수를 사용하여 변수 상태를 변화시키도록 하였다.

update 는 해당 프로바이더가 관리하고있는 변수의 데이터를 변경시키는 것이다.

 

count_view.dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_exam/provider/count_provider.dart';

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

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final count = ref.watch(countProviderProvider).value;
    final countproviderNotifier = ref.watch(countProviderProvider.notifier);

    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ElevatedButton(
              onPressed: () async{
                await countproviderNotifier.countUp();
              },
              child: const Text(
                "Plus",
                style: TextStyle(fontSize: 20, fontWeight: FontWeight.w500),
              )),
          const SizedBox(
            height: 10,
          ),
          Text(
            count.toString(),
            style: const TextStyle(fontSize: 30, fontWeight: FontWeight.w500),
          )
        ],
      ),
    );
  }
}

 

 

final count = ref.watch(countProviderProvider).value; 는 프로바이더가 관리하고있는 데이터를 가져와서 보여주는 것이다.

여기서 데이터를 가져오는 방식은 read, watch, listen가 있는데, riverpod 공식문서에서 watch를 사용하도록 권장한다.

하지만 watch만 사용했을때 에러가나는 경우도 있기 때문에, 이 세 가지 방식에 대해선 따로 공부해서 올리겠다.

 

final countproviderNotifier = ref.watch(countProviderProvider.notifier); 는 프로바이더에서 작성한 함수를 호출하기 위해 사용하는 것이다.

countproviderNotifier.countUp() 으로 사용할 수 있다.

 

결과

 

반응형