๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Mobile/Flutter

[Flutter] Riverpod ์ •๋ฆฌ..

๋ฐ˜์‘ํ˜•

 

Provider ํƒ€์ž… ์ƒํƒœ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ? ์‚ฌ์šฉ ์˜ˆ์‹œ
Provider (@riverpod ๊ธฐ๋ณธ ํ•จ์ˆ˜) โŒ ์ฝ๊ธฐ๋งŒ ๊ฐ€๋Šฅ ref.watch(isLoadingProvider)
StateProvider โœ… ๊ฐ€๋Šฅ ref.read(isLoadingProvider.notifier).state = true;
@riverpod class (StateNotifier) โœ… ๊ฐ€๋Šฅ ref.read(isLoadingProvider.notifier).set(true);

 

 

provider๋ฅผ ์ •์˜ํ•˜๋Š” ๊ตฌ๋ฌธ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

(์ƒํƒœ๋ฅผ ์ฝ๊ธฐ๋งŒ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ถˆ๋ณ€ ๊ฐ’)

@riverpod
Result myFunction(Ref ref) {
  <your logic here>
}

 

์–ด๋…ธํ…Œ์ด์…˜๋œ ํ•จ์ˆ˜(annotated function)

์–ด๋…ธํ…Œ์ด์…˜๋œ ํ•จ์ˆ˜์˜ ์ด๋ฆ„์— ๋”ฐ๋ผ provider์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ๋ฐฉ์‹์ด ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค.
์ฃผ์–ด์ง„ ํ•จ์ˆ˜ myFunction์— ๋Œ€ํ•ด ์ƒ์„ฑ๋œ myFunctionProvider ๋ณ€์ˆ˜๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

์–ด๋…ธํ…Œ์ด์…˜๋œ ํ•จ์ˆ˜๋Š” ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ "ref"๋ฅผ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๊ทธ ์™ธ์—๋„ ํ•จ์ˆ˜๋Š” ์ œ๋„ค๋ฆญ์„ ํฌํ•จํ•˜์—ฌ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ์›ํ•  ๊ฒฝ์šฐ Future/Stream์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ํ•จ์ˆ˜๋Š” provider๋ฅผ ์ฒ˜์Œ ์ฝ์„ ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
์ดํ›„ ์ฝ๊ธฐ๋Š” ํ•จ์ˆ˜๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ  ๋Œ€์‹  ์บ์‹œ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

 

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'activity.dart';

// ์ฝ”๋“œ ์ƒ์„ฑ์ด ์ž‘๋™ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
part 'provider.g.dart';

/// ๊ทธ๋Ÿฌ๋ฉด ์ด ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ๋ฅผ ์บ์‹œํ• 
/// `activityProvider`๋ผ๋Š” provider๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
@riverpod
Future<Activity> activity(Ref ref) async {
  // package:http๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Bored API์—์„œ ์ž„์˜์˜ activity๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
  final response = await http.get(Uri.https('boredapi.com', '/api/activity'));
  // ๊ทธ๋Ÿฐ ๋‹ค์Œ dart:convert๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ JSON ํŽ˜์ด๋กœ๋“œ๋ฅผ ๋งต ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋กœ ๋””์ฝ”๋”ฉํ•ฉ๋‹ˆ๋‹ค.
  final json = jsonDecode(response.body) as Map<String, dynamic>;
  // ๋งˆ์ง€๋ง‰์œผ๋กœ ๋งต์„ Activity ์ธ์Šคํ„ด์Šค๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  return Activity.fromJson(json);
}

 

โœ… ์˜ˆ์ œ: ์ผ๋ฐ˜ Provider vs @riverpod ๋ฒ„์ „

1. ๊ธฐ์กด ๋ฐฉ์‹

final nameProvider = Provider<String>((ref) => 'ํ™๊ธธ๋™');

2. @riverpod ๋ฐฉ์‹ (codegen)

import 'package:flutter_riverpod/flutter_riverpod.dart';

part 'my_provider.g.dart'; // ์ค‘์š”!

@riverpod
String name(NameRef ref) {
  return 'ํ™๊ธธ๋™';
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ž๋™์œผ๋กœ nameProvider๊ฐ€ ์ƒ์„ฑ!

โœ… ์ฐจ์ด์  ์ •๋ฆฌ

ํ•ญ๋ชฉ @riverpod ๋ฐฉ์‹ ๊ธฐ์กด ๋ฐฉ์‹
์ฝ”๋“œ ๊ธธ์ด ๋” ์งง๊ณ  ๊ฐ„๊ฒฐํ•จ ์ข€ ๋” ๊ธธ๊ณ  ๊ตฌ์กฐ์ 
์ฝ”๋“œ ์ƒ์„ฑ ํ•„์š” (build_runner) ํ•„์š” ์—†์Œ
ํƒ€์ž… ์•ˆ์ „์„ฑ, ์ž๋™์™„์„ฑ ๋งค์šฐ ์ข‹์Œ ๊ดœ์ฐฎ์Œ
์œ ์ง€๋ณด์ˆ˜ ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์— ์œ ๋ฆฌ ์ดˆ๋ฐ˜์€ ๋‹จ์ˆœํ•จ

 

โœ… ํ•œ ์ค„ ์š”์•ฝ

@riverpod์œผ๋กœ ๋งŒ๋“  counterProvider๋Š” ๊ธฐ์กด์˜ StateNotifierProvider์™€ StateNotifier๋ฅผ ๋” ๊น”๋”ํ•˜๊ฒŒ ์ž๋™์œผ๋กœ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๋ฐฉ์‹์ด์—์š”.

 

 

Notifiers๋Š” providers์˜ "์ƒํƒœ์ €์žฅ ์œ„์ ฏ(stateful widget)"์ž…๋‹ˆ๋‹ค. provider๋ฅผ ์ •์˜ํ•˜๋Š” ๋ฌธ๋ฒ•์„ ์•ฝ๊ฐ„ ์ˆ˜์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์ด ์ƒˆ๋กœ์šด ๋ฌธ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

@riverpod
class MyNotifier extends _$MyNotifier {
  @override
  Result build() {
    <your logic here>
  }
  <your methods here>
}

 

@riverpod
class TodoList extends _$TodoList {
  @override
  Future<List<Todo>> build() async {
    // ์ด์ „์— FutureProvider์— ์žˆ๋˜ ๋กœ์ง์ด ์ด์ œ build ๋ฉ”์„œ๋“œ์— ์žˆ์Šต๋‹ˆ๋‹ค.
    return [
      Todo(description: 'Learn Flutter', completed: true),
      Todo(description: 'Learn Riverpod'),
    ];
  }
}

์–ด๋…ธํ…Œ์ด์…˜(annotation)

๋ชจ๋“  providers๋Š” @riverpod ๋˜๋Š” @Riverpod()๋กœ ์–ด๋…ธํ…Œ์ด์…˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์–ด๋…ธํ…Œ์ด์…˜์€ ์ „์—ญ ํ•จ์ˆ˜๋‚˜ ํด๋ž˜์Šค์— ๋ฐฐ์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด provider๋ฅผ ์„ค์ •(config)ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, @Riverpod(keepAlive: true)๋ฅผ ์ž‘์„ฑํ•˜์—ฌ "auto-dispose"(๋‚˜์ค‘์— ์‚ดํŽด๋ณผ ๊ฒƒ์ž„)๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Notifier

@riverpod ์–ด๋…ธํ…Œ์ด์…˜์ด ํด๋ž˜์Šค์— ๋ฐฐ์น˜๋˜๋ฉด ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ "Notifier"๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.
ํด๋ž˜์Šค๋Š” _$NotifierName์„ ํ™•์žฅํ•ด์•ผ ํ•˜๋ฉฐ, ์—ฌ๊ธฐ์„œ NotifierName์€ ํด๋ž˜์Šค ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.

Notifiers๋Š” provider์˜ ์ƒํƒœ(state)๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๋…ธ์ถœํ•  ์ฑ…์ž„์ด ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ํด๋ž˜์Šค์˜ ๊ณต๊ฐœ ๋ฉ”์„œ๋“œ๋Š” ref.read(yourProvider.notifier).yourMethod()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ consumer๊ฐ€ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

UI์—์„œ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ๋Š” ์ˆ˜๋‹จ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์—, Notifiers์—๋Š” ๊ธฐ๋ณธ ์ œ๊ณต 'state' ์™ธ์— ๊ณต๊ฐœ ์†์„ฑ์ด ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

 

โœ… ์ง€๊ธˆ Riverpod 2.0์—์„œ ์‹ค์ œ๋กœ "ํ•ต์‹ฌ์ ์œผ๋กœ ์“ฐ๋Š” ๊ฒƒ"

โœ… 1. @riverpod + ํ•จ์ˆ˜

@riverpod
String name(NameRef ref) => 'ํ™๊ธธ๋™';
 

๐Ÿ‘‰ ๊ธฐ์กด์˜ Provider ๊ธฐ๋Šฅ์„ ์ž๋™ ์ƒ์„ฑ

โœ… 2. @riverpod + Notifier ํด๋ž˜์Šค

@riverpod
class Counter extends _$Counter {
  @override
  int build() => 0;

  void increment() => state++;
}
 

 ๐Ÿ‘‰ ๊ธฐ์กด์˜ StateNotifierProvider + StateNotifier` ์กฐํ•ฉ์„ ๋Œ€์ฒด

 

๊ณผ๊ฑฐ ๋ฐฉ์‹ 2.0 ๋ฐฉ์‹ ๋ฐฉ์‹
Provider @riverpod ํ•จ์ˆ˜
StateNotifierProvider @riverpod class extends _$...
StateProvider ๊ฑฐ์˜ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์ฝ”๋“œ ์ƒ์„ฑ์€ ์—†์Œ

 

โœ… ์‹ค์ œ๋กœ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ, Riverpod 2.0์—์„œ๋Š” @riverpod ๊ธฐ๋ฐ˜์˜ Provider๋ž‘ Notifier ๋‘ ๊ฐ€์ง€๋งŒ์œผ๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

ํ˜•ํƒœ ์—ญํ•  ๋Œ€์ฒด๋˜๋Š” ์ „ํ†ต์  Provid
ํ˜•ํƒœ ์—ญํ•  ๋Œ€์ฒด๋˜๋Š” ์ „ํ†ต์  Provider
@riverpod ํ•จ์ˆ˜ ์ฝ๊ธฐ ์ „์šฉ ๊ฐ’, ๊ณ„์‚ฐ๋œ ๊ฐ’ Provider, FutureProvider, StreamProvider
@riverpod class extends _$Notifier<T> ๋™๊ธฐ ์ƒํƒœ, ๋กœ์ง ํฌํ•จ StateNotifierProvider
@riverpod class extends _$AsyncNotifier<T> ๋น„๋™๊ธฐ ์ƒํƒœ (API ๋“ฑ) FutureProvider, AsyncNotifier, StreamProvider

 

โœ… ๊ทธ๋ž˜์„œ ์‹ค์ œ๋กœ ํ•„์š”ํ•œ ๊ฑด

  1. @riverpod ํ•จ์ˆ˜
    → Provider, FutureProvider, StreamProvider ๋Œ€์ฒด ๊ฐ€๋Šฅ
  2. @riverpod class extends _$Notifier<T>
    → StateNotifierProvider ๋Œ€์ฒด
  3. (์˜ต์…˜) @riverpod class extends _$AsyncNotifier<T>
    → ๋น„๋™๊ธฐ ์ž‘์—…์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋งŒ ์‚ฌ์šฉ

โ“๊ทธ๋Ÿผ StateProvider๋Š”?

  • ์—ฌ์ „ํžˆ ์•„์ฃผ ๊ฐ„๋‹จํ•œ ์ƒํƒœ (ํ† ๊ธ€, ์ˆซ์ž ๋“ฑ) ์—๋Š” ํŽธํ•ด์„œ ์“ธ ์ˆ˜ ์žˆ์–ด์š”.
  • ํ•˜์ง€๋งŒ ๊ตฌ์กฐ์ ์œผ๋กœ ๋” ๊น”๋”ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•˜๋ ค๋ฉด Notifier๋กœ ์ „ํ™˜ํ•˜๋Š” ๊ฒŒ ์ข‹์•„์š”.

โœ… ํ•œ ์ค„ ์ •๋ฆฌ

์ง€๊ธˆ Riverpod 2.0์—์„œ๋Š” @riverpod ๊ธฐ๋ฐ˜์˜ Provider์™€ Notifier (ํ•„์š” ์‹œ AsyncNotifier)๋งŒ์œผ๋กœ ๋Œ€๋ถ€๋ถ„์˜ ์ƒํƒœ ๊ด€๋ฆฌ๊ฐ€ ๋๋‚˜์š”.

 

์ง€๊ธˆ Riverpod 2.0์—์„œ๋Š” @riverpod ์ฝ”๋“œ ์ƒ์„ฑ ๊ธฐ๋ฐ˜ ๊ตฌ์กฐ๊ฐ€ ๋Œ€๋ถ€๋ถ„์„ ๋Œ€์ฒดํ•˜์ง€๋งŒ,
StateProvider๋งŒํผ ๊ฐ„๋‹จํ•œ ๊ธฐ๋Šฅ์„ ์ •ํ™•ํžˆ ๋Œ€์ฒดํ•˜๋Š” ๊ตฌ์กฐ๋Š” ์—†์Šต๋‹ˆ๋‹ค.

 

 

โœ… ์™œ StateProvider๋Š” ๋Œ€์ฒด๋˜์ง€ ์•Š์•˜์„๊นŒ?

์ด์œ  ์„ค๋ช…
๋„ˆ๋ฌด ๋‹จ์ˆœํ•จ ์ˆซ์ž ํ•˜๋‚˜, bool ํ•˜๋‚˜ ์ƒํƒœ ๊ด€๋ฆฌํ•  ๋•Œ ๋”ฑ ์ข‹์Œ
๋ณ„๋„ ํด๋ž˜์Šค ๋ถˆํ•„์š” Notifier์ฒ˜๋Ÿผ ํด๋ž˜์Šค ์•ˆ ๋งŒ๋“ค๊ณ  ํ•œ ์ค„๋กœ ๋๋ƒ„
๋น ๋ฅด๊ฒŒ ํ…Œ์ŠคํŠธ์šฉ ์ƒํƒœ ๋งŒ๋“ค๊ธฐ ์ข‹์Œ UI ํ…Œ์ŠคํŠธ๋‚˜ ์ž„์‹œ ์ƒํƒœ์— ์œ ๋ฆฌ

 

โœ… ์ •๋ฆฌ: ํ˜„์žฌ ๊ตฌ์กฐ์—์„œ์˜ ์—ญํ•  ๋ถ„๋‹ด

๋ชฉ์  ์ถ”์ฒœ ๋ฐฉ์‹ ๋น„๊ณ 
๋‹จ์ˆœํ•œ ๊ฐ’ (int, bool ๋“ฑ) โœ… StateProvider ์—ฌ์ „ํžˆ ์œ ์šฉํ•จ
์ฝ๊ธฐ ์ „์šฉ ๊ฐ’ โœ… @riverpod ํ•จ์ˆ˜ ๊ธฐ์กด Provider ๋Œ€์ฒด
๋กœ์ง ํฌํ•จ ๋™๊ธฐ ์ƒํƒœ โœ… @riverpod + Notifier ๊ธฐ์กด StateNotifier ๋Œ€์ฒด
๋น„๋™๊ธฐ ์ƒํƒœ โœ… @riverpod + AsyncNotifier ๊ธฐ์กด FutureProvider ๋“ฑ ๋Œ€์ฒด

 

โœ… ํ•œ ์ค„ ์š”์•ฝ

StateProvider๋Š” ํ˜„์žฌ๋„ ๋Œ€์ฒด๋˜์ง€ ์•Š์•˜๊ณ , Riverpod 2.0์—์„œ๋„ ์—ฌ์ „ํžˆ ์‚ด์•„ ์žˆ๋Š” "์‹ฌํ”Œํ•œ ์ƒํƒœ ๊ด€๋ฆฌ ๋„๊ตฌ"์˜ˆ์š”.

 

ํ•„์š”ํ•˜๋‹ค๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ Notifier๋กœ StateProvider์ฒ˜๋Ÿผ ํ‰๋‚ด๋‚ด๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ…
์†”์งํžˆ ๋„ˆ๋ฌด ์˜ค๋ฒ„์—”์ง€๋‹ˆ์–ด๋ง์ด์—์š” ๐Ÿ˜…

@riverpod
class SimpleInt extends _$SimpleInt {
  @override
  int build() => 0;

  void set(int value) => state = value;
  void increment() => state++;
}

 

 

 

StatelessWidget/StatefulWidget์ด Consumer๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋Œ€์‹  ConsumerWidget/ConsumerStatefulWidget์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ConsumerWidget๊ณผ ConsumerStatefulWidget์€ ์‚ฌ์‹ค์ƒ StatelessWidget/StatefulWidget๊ณผ Consumer๋ฅผ ๊ฒฐํ•ฉํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋“ค์€ ์›๋ž˜์˜ ์ง๊ณผ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•˜์ง€๋งŒ "ref"๋ฅผ ์ œ๊ณตํ•œ๋‹ค๋Š” ์ถ”๊ฐ€์ ์ธ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

ConsumerWidget

/// "StatelessWidget" ๋Œ€์‹  "ConsumerWidget"์„ ์„œ๋ธŒํด๋ž˜์Šคํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค.
/// ์ด๋Š” "StatelessWidget"์„ ๋งŒ๋“ค๊ณ  "Consumer"๋ฅผ ์žฌ์กฐ์ •ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
class Home extends ConsumerWidget {
  const Home({super.key});

  @override
  // ์ด์ œ "build"๊ฐ€ ์ถ”๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜ "ref"๋ฅผ ๋ฐ›๋Š” ๋ฐฉ์‹์— ์ฃผ๋ชฉํ•˜์„ธ์š”
  Widget build(BuildContext context, WidgetRef ref) {
    // "Consumer"๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์œ„์ ฏ ๋‚ด๋ถ€์—์„œ "ref.watch"๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    final AsyncValue<Activity> activity = ref.watch(activityProvider);

    // ๋ Œ๋”๋ง ๋กœ์ง์€ ๋™์ผํ•˜๊ฒŒ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.
    return Center(/* ... */);
  }
}

 

ConsumerStatefulWidget

// ConsumerStatefulWidget์„ ํ™•์žฅํ•ฉ๋‹ˆ๋‹ค.
// ์ด๊ฒƒ์€ "Consumer" + "StatefulWidget"๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.
class Home extends ConsumerStatefulWidget {
  const Home({super.key});

  @override
  ConsumerState<ConsumerStatefulWidget> createState() => _HomeState();
}

// "State" ๋Œ€์‹  "ConsumerState"๋ฅผ ํ™•์žฅํ•œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
// ์ด๊ฒƒ์€ "ConsumerWidget" ๋Œ€ "StatelessWidget"๊ณผ ๋™์ผํ•œ ์›๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
class _HomeState extends ConsumerState<Home> {
  @override
  void initState() {
    super.initState();

    // ์ƒํƒœ ์ˆ˜๋ช… ์ฃผ๊ธฐ์—๋„ "ref"์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    // ์ด๋ฅผ ํ†ตํ•ด ํŠน์ • provider์— ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋Œ€ํ™” ์ƒ์ž/์Šค๋‚ต๋ฐ”๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    ref.listenManual(activityProvider, (previous, next) {
      // TODO ์Šค๋‚ต๋ฐ”/๋Œ€ํ™” ์ƒ์ž ํ‘œ์‹œ
    });
  }

  @override
  Widget build(BuildContext context) {
    // "ref"๋Š” ๋” ์ด์ƒ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ๋˜์ง€ ์•Š๊ณ  ๋Œ€์‹  "ConsumerState"์˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
    // ๋”ฐ๋ผ์„œ "build" ๋‚ด์—์„œ "ref.watch"๋ฅผ ๊ณ„์† ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    final AsyncValue<Activity> activity = ref.watch(activityProvider);

    return Center(/* ... */);
  }
}
๋ฐ˜์‘ํ˜•

'Mobile > Flutter' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Flutter] Erros..  (0) 2023.03.08
[Flutter] Write your first Flutter app, part 1  (1) 2022.06.07
[Flutter]  (0) 2022.05.20
์ฃผ์„  (2) 2020.05.18
Dart cheatsheet codelab  (0) 2020.01.02