Riverpod 가 좋은 상태관리 라이브러리 이지만 초보자에겐 어렵다는 것에 공감한다.
하나씩 이해하기 위해서 기록하고 수정 보완하려고 한다.
Flutter riverpod 자동 생성하는 방법이다.
# 상태관리툴 라이브러리 riverpod 추가
flutter pub add flutter_riverpod riverpod_annotation
flutter pub add -d riverpod_generator
|
@riverpod 를 어노테이션을 사용하여 riverpod 자동 생성을 할 수 있다.
함수로 정의하는 경우와 클래스로 정의하는 경우가 있는데, 클래스로 정의하는 경우를 더 많이 사용할 거 같다.
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'sample_provider.g.dart';
/***
* 1) 어떤 Provider를 사용할지 결정할 고민 필요없도록
* 2) Parameter > Family 파라미터를 일반 함수처럼 사용할 수 있도록
*
* 함수명 gState 에서 첫글자를 대문자로 변경하고, Ref 를 붙인다. GStateRef ref
* 함수 정의 이후 dart run build_runner build 명령어를 터미널 창에서 실행한다.
*/
@riverpod
String gState(GStateRef ref) {
return 'Code Generation Riverpod';
}
// final _gStateProvider = Provider<String>((ref) => 'Code Generation Riverpod');
@riverpod
int gStateMultiply(GStateMultiplyRef ref, {
required int number1,
required int number2,
}){
return number1 * number2;
}
@riverpod
class GNotifier extends _$GNotifier {
@override
int build() {
return 0;
}
increment(){
state++;
}
decrement() {
state--;
}
}
@riverpod
class MyNotifier extends _$MyNotifier {
@override
List<String> build() {
return [];
}
void addString(String stringToAdd) {
state = [...state, stringToAdd];
}
}
|
함수처럼 정의하여 사용하는 경우와 Class 로 정의하여 사용하는 경우를 예시하고 있다.
자동으로 생성하지 않고 직접 구현하는 경우의 코드.
import 'package:riverpod_annotation/riverpod_annotation.dart';
final myNotifierProvider = NotifierProvider<MyNotifier, List<String>>(MyNotifier.new);
class MyNotifier extends Notifier<List<String>> {
// List<String> 이 state 를 의미하고, 반환타입이다.
@override
List<String> build() {
return []; // 상태(state) 초기값 정의
}
void addString(String stringToAdd){
state = [...state, stringToAdd];
}
}
|
자동으로 생성한 코드
아래 코드와 위의 코드는 서로 같은 결과를 반환한다.
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'my_provider.g.dart';
@riverpod
class MyNotifier extends _$MyNotifier {
@override
List<String> build() {
return [];
}
void addString(String stringToAdd) {
state = [...state, stringToAdd];
}
}
|
UI에 출력하여 결과를 확인해보자.
최상위에 ProviderScope를 지정하여 project 전반에 프로바이더 선언/접근을 가능하게 한다.
void main() {
runApp(
ProviderScope(
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Riverpod Autho Generation Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: HomeScreen(),
);
}
}
|
Riverpod를 읽기 위해서는 ref 객체가 필요하다.
ref 객체는 일반적으로 사용하는 StatelessWidget 에서는 얻을 수 없고, ConsumerWidget을 사용하거나 사용하고 싶은 위젯 부분에서 Consumer 위젯으로 감싸면 ref 객체를 얻을 수 있다.
build() 메서드 내부에 선언한 listOfString 변수는 ref 객체의 watch 메서드를 사용하여 myNotifierProvider의 List<String> 타입의 상태값을 받아온다.
myNotifierProvider의 상태가 변할 때마다 감지할 수 있고 위젯을 리빌드 할 수 있다.
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_v2/provider/sample_provider.dart';
class HomeScreen extends ConsumerWidget {
HomeScreen({Key? key}) : super(key: key);
Random random = new Random();
@override
Widget build(BuildContext context, WidgetRef ref) {
final listOfString = ref.watch(myNotifierProvider) as List;
ref.listen<List>(myNotifierProvider, (List? prevState, List newState) {
print('This function have been called');
});
return Scaffold(
appBar: AppBar(
title: Text('Riverpod Sample'),
centerTitle: true,
actions: [
IconButton(
onPressed: () {
ref
.read(myNotifierProvider.notifier)
.addString('string ${random.nextInt(100)}');
},
icon: const Icon(Icons.add),
),
],
),
body: Center(
child: Column(
children: [
...listOfString.map(
(string) => Text(string),
),
],
),
),
);
}
}
|
자동으로 생성하는 CRUD 예제를 더 보강할 예정이다.
Riverpod 를 생성하는 기본 사항을 알고 나면, Dart 언어를 잘 다루는 것이 중요하다는 걸 많이 느끼고 있다.
Dart asMap 에 대한 Dart 문법은 https://link2me.tistory.com/2372 를 참조하면 도움된다.
'Flutter 앱 > 상태관리' 카테고리의 다른 글
Flutter Provider 상태관리 예제 (0) | 2024.01.06 |
---|---|
Flutter Riverpod 예제 : Bucket List (0) | 2023.12.27 |
Flutter StatefulWidget (0) | 2023.12.13 |
Flutter Riverpod - NotifierProvider.family (0) | 2023.12.11 |
Flutter Riverpod - NotifierProvider (0) | 2023.12.11 |