// ignore_for_file: prefer_const_constructors
// 58:26 (https://www.youtube.com/watch?v=vtGCteFYs4M)
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
void main() {
// riverpod을 사용하기 위해 ProviderScope로 뚜껑을 감싸줌
runApp(ProviderScope(child: const App()));
}
// null값 계산을 위한 +연산자오버로딩
extension OptionalInfixAddition<T extends num> on T? {
T? operator +(T? other) {
final shadow = this;
if (shadow != null) {
return shadow + (other ?? 0) as T;
} else {
return null;
}
}
}
// getx와 같은 상태를 관리할 함수저장소
class Counter extends StateNotifier<int?> {
Counter() : super(null);
// 연산자오버로딩 처리를 하였기 때문에 null값에 대한 오류가 발생하지 않음.
void increment() => state = state == null ? 1 : state + 1;
// void increment() => state++;
int? get value => state;
}
// 프로바이더변수
final counterProvider = StateNotifierProvider<Counter, int?>(
(ref) => Counter(),
);
class App extends StatelessWidget {
const App({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
darkTheme: ThemeData.dark(),
themeMode: ThemeMode.dark,
debugShowCheckedModeBanner: false,
home: const HomePage(),
);
}
}
// 구독위젯이 들어갈 컨슈머위젯
class HomePage extends ConsumerWidget {
const HomePage({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
// appBar: AppBar(title: Text('Hooks Riverpod')),
appBar: AppBar(
// obx와 같은 구독 위젯
title: Consumer(
builder: (context, ref, child) {
final count = ref.watch(counterProvider);
final text = count == null ? 'Press the button' : count.toString();
return Text(text);
},
),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextButton(
onPressed: () {
ref.read(counterProvider.notifier).increment();
},
child: const Text('Increment counter'),
),
],
),
);
}
}