① screen/future_provider_screen.dart 파일 생성하기


② HomeScreen에 FutureProviderScreen 등록

그러면 홈스크린 화면에서 FutureProviderScreen 버튼이 추가된 걸 확인할 수 있다.

③ FutureProvider 만들기
riverpod/future_provider.dart 파일 생성한다.
그리고 나는 List로 된 int를 리턴 해줄 거임.
(future_provider.dart에다가는 실제 async 요청을 가정해서 연습!)

자동완성되고... 완성 된 코드를 보면 기본 형태(구조)는 각각 provider들과 비슷하다는 걸 볼 수 있다.
✔ 다만, 각 provider의 제너릭( < > )에 들어가는 값과, 리턴을 주는 값(null 자리)이 다를 뿐!

import 'package:flutter_riverpod/flutter_riverpod.dart';
final multiplesFutureProvider = FutureProvider<List<int>>((ref) => null);
④ async(비동기)로 만들어주기
async로 만들고 future.delayed로 2초 정도 기다렸다가,
List 형태의 숫자들을 반환하게 해볼거임.
import 'package:flutter_riverpod/flutter_riverpod.dart';
final multiplesFutureProvider = FutureProvider<List<int>>((ref) async {
await Future.delayed(
const Duration(seconds: 2),
);
return [1, 2, 3, 4, 5];
});
⑤ FutureProviderScreen 수정하기
⑤-1. StatelessWidget을 ConsumerWidget으로 변경
FutureProviderScreen에서 StatelessWidget을 ConsumerWidget으로 변경해준다.
⑤-2. build 함수에 WidgetRef ref 추가
build 함수에 WidgetRef ref 파라미터를 추가해준다

⑥ ref.watch 해 주기
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_study/layout/defalut_layout.dart';
import 'package:riverpod_study/riverpod/future_provider.dart';
class FutureProviderScreen extends ConsumerWidget {
const FutureProviderScreen({super.key});
Widget build(BuildContext context, WidgetRef ref) {
// watch 해주기
final state = ref.watch(multiplesFutureProvider);
return const DefalutLayout(
title: 'FutureProviderScreen',
body: Column(
children: [],
),
);
}
}
지금까지 사용해본 provider에서는 동기 형태로 반환되는 상태였는데,
이번에는 FutureProvider에서는 2초간 비동기로 기다리는 시간이 있음!
그럼 이게 어떻게 처리되는걸까?
👉 .when 을 해 주면 자동완성으로 data, error, loading이라는 파라미터가 나옴

✔ data는 loading이 끝나가지고 데이터가 있을 때 실행는 함수
✔ error는 에러가 났을 때 실행되는 함수
✔ loading은 로딩되고 있을 때 실행되는 함수
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_study/layout/defalut_layout.dart';
import 'package:riverpod_study/riverpod/future_provider.dart';
class FutureProviderScreen extends ConsumerWidget {
const FutureProviderScreen({super.key});
Widget build(BuildContext context, WidgetRef ref) {
// watch 해주기
final state = ref.watch(multiplesFutureProvider);
return DefalutLayout(
title: 'FutureProviderScreen',
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
state.when(
data: (data) {
return Text(
data.toString(),
textAlign: TextAlign.center,
);
},
error: (err, stack) => Text(
err.toString(),
),
loading: () => const Center(
child: CircularProgressIndicator(),
),
),
],
),
);
}
}
error
error에는 에러 내용, stack를 받을 수 있음.
그리고 에러가 나면 text를 반환하도록 하겠음...
loading
나는 loading 상태일 땐 아무 것도 파라미터에 받지 않고,
그냥 CircularProgressIndicator 넣어줄거임.

앱 재실행 후에 FutureProviderScreen 버튼을 누르고 들어가면...

로딩이 2초간 되고...

이렇게 List 형태의 int 값이 반환되는 걸 확인할 수 있다.
error를 일부러 내보자!

앱을 재실행하고 FutureProviderScreen 버튼을 누르면...

똑같이 2초간 로딩되고...

에러 문구가 던져진다.

왜 이렇게 나오는걸까???
FutureProviderScreen 코드를 보면...
error가 발생했을 때, 에러 값을 그냥 Text에 넣고 String으로 반환하라고 했으니깐!

⑧ AsyncValue 상태로 들어오도록 하기

⭐생각하고 있어야할 것!
final state 이 상태를 받았을 때, 이 상태는 AsyncValue라는 상태로 들어오게 된다!
그리고 이 AsyncValue는 .when 함수가 무조건 들어있음!
이 .when 함수로 data가 들어있을 때, error가 있을 때, loading 중일 때
경우를 따로 named Parameter로 함수를 써서 표현할 수 있다!
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_study/layout/defalut_layout.dart';
import 'package:riverpod_study/riverpod/future_provider.dart';
class FutureProviderScreen extends ConsumerWidget {
const FutureProviderScreen({super.key});
Widget build(BuildContext context, WidgetRef ref) {
// watch 해주기
final AsyncValue state = ref.watch(multiplesFutureProvider);
return DefalutLayout(
title: 'FutureProviderScreen',
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
state.when(
data: (data) {
return Text(
data.toString(),
textAlign: TextAlign.center,
);
},
error: (err, stack) => Text(
err.toString(),
),
loading: () => const Center(
child: CircularProgressIndicator(),
),
),
],
),
);
}
}
⑨ Exception 주석처리
에러를 다시 지우고 앱을 재실행하면 2초 뒤에 데이터가 다시 잘 나옴.
error로 간 게 아니라 data로 갔으니깐~