AsyncValue vs AsyncData
| topics | 500-모바일개발 501 Flutter 504 Riverpod |
| types | 이론 레퍼런스 |
| tags | #flutter #riverpod #asyncvalue |
| references | github.com/rrousselGit/riverpod/discu... riverpod.dev/docs/concepts/reading |
AsyncValue vs AsyncData
Riverpod에서 비동기 상태를 다루는 타입들의 차이다.
AsyncValue 구조
sealed class AsyncValue<T> {
// 세 가지 하위 클래스
}
class AsyncData<T> extends AsyncValue<T> {
final T value;
}
class AsyncLoading<T> extends AsyncValue<T> {}
class AsyncError<T> extends AsyncValue<T> {
final Object error;
final StackTrace stackTrace;
}
핵심 차이
- AsyncValue: 로딩, 데이터, 에러 상태를 모두 포함하는 Sealed Class
- AsyncData: AsyncValue의 하위 클래스로, 데이터가 있는 상태만 나타냄
사용 예시
when - 모든 상태 처리
final userState = ref.watch(userProvider);
userState.when(
loading: () => CircularProgressIndicator(),
error: (e, stack) => Text('Error: $e'),
data: (user) => Text(user.name),
);
maybeWhen - 일부 상태만 처리
userState.maybeWhen(
data: (user) => Text(user.name),
orElse: () => CircularProgressIndicator(),
);
whenData - 데이터만 변환
final nameState = userState.whenData((user) => user.name);
// AsyncValue<User> → AsyncValue<String>
유용한 프로퍼티
// 현재 상태 확인
userState.isLoading // 로딩 중인가
userState.hasError // 에러인가
userState.hasValue // 데이터가 있는가
// 값 접근
userState.value // T? - null일 수 있음
userState.valueOrNull // T? - value와 동일
userState.requireValue // T - null이면 에러
AsyncValue.guard
try-catch 대신 사용하면 깔끔하다.
// 이전 방식
try {
state = AsyncValue.data(await fetchUser());
} catch (e, stack) {
state = AsyncValue.error(e, stack);
}
// AsyncValue.guard
state = await AsyncValue.guard(() => fetchUser());
이전 값 유지하기
로딩 중에도 이전 값을 보여주고 싶을 때.
final userState = ref.watch(userProvider);
// isLoading이면서 value가 있을 수 있음
if (userState.isLoading && userState.hasValue) {
return Stack(
children: [
UserWidget(user: userState.value!),
LoadingOverlay(),
],
);
}