티스토리 뷰
Flutter에서 일정 추가 기능을 구현할 때 서버와의 통신 시간이 걸리더라도 화면이 끊기지 않게 하려면 어떻게 해야 할까?
오늘은 "낙관적 업데이트(Optimistic Update)" 패턴을 적용한 코드를 살펴보자.
문제 상황
Schedule을 추가할 수 있는 간단한 UI를 구현한 다음, 여기에 3월 15일 오후 2시 회의 일정을 추가한다고 해보자.
서버에 저장 요청을 보낸 뒤 응답을 기다리는 동안 아무 반응이 없다면 사용자 경험이 좋다고 볼 수 없으니..!
여기서 낙관적 업데이트 패턴을 적용하면 이런 문제를 해결할 수 있다.
화면 예시
코드 예시
class ScheduleProvider extends ChangeNotifier {
final ScheduleRepository repository;
DateTime selectedDate = DateTime.now().toUtc();
Map<DateTime, List> cache = {};
ScheduleProvider({required this.repository}) {
getSchedules(date: selectedDate);
}
void createSchedule({required ScheduleModel schedule}) async {
final targetDate = schedule.date;
const uuid = Uuid();
final tempId = uuid.v4();
final newSchedule = schedule.copyWith(id: tempId);
cache.update(
targetDate,
(value) => [...value, newSchedule]..sort((a, b) => a.startTime.compareTo(b.startTime)),
ifAbsent: () => [newSchedule],
);
notifyListeners();
try {
final savedSchedule = await repository.createSchedule(schedule: schedule);
cache.update(
targetDate,
(value) => value
.map((e) => e.id == tempId ? e.copyWith(id: savedSchedule) : e)
.toList(),
);
} catch (e) {
cache.update(
targetDate,
(value) => value.where((e) => e.id != tempId).toList(),
);
}
notifyListeners();
}
}
코드 동작 흐름
1. 임시 ID 생성
사용자가 일정을 추가하려고 하면 먼저 Uuid
라이브러리를 사용해서 임시 ID를 만든다.
예) "temp-123-456"
const uuid = Uuid();
final tempId = uuid.v4();
2. 즉시 UI 업데이트
생성된 임시 ID와 함께 캐시를 업데이트한다.
서버 응답을 기다리지 않고 화면에 새 일정이 바로 표시된다.
cache.update(
targetDate,
(value) => [...value, newSchedule]..sort((a, b) => a.startTime.compareTo(b.startTime)),
ifAbsent: () => [newSchedule],
);
notifyListeners();
예) 3월 15일 캐시에 추가되는 데이터
- ID: temp-123-456
- 내용: "회의"
- 시간: "14:00"
3. 서버 저장
이제 서버에 요청을 보내서 실제 일정을 저장하면 서버는 새로 생성된 ID를 반환해준다.
예) "server-789"
라는 ID를 돌려줌
4. 성공 시 ID 교체
서버에서 받은 ID로 캐시에 저장된 임시 ID를 교체한다.
화면에는 전혀 변화가 없기 때문에 사용자는 이 과정이 진행된 걸 모른다.
cache.update(
targetDate,
(value) => value.map((e) => e.id == tempId ? e.copyWith(id: savedSchedule) : e).toList(),
);
5. 실패 시 롤백
만약 서버 저장이 실패했다면 캐시에서 해당 일정을 삭제한다.
추가된 일정이 사라지는 걸 보이기 전에 적절히 오류 화면을 처리해주면 된다.
cache.update(
targetDate,
(value) => value.where((e) => e.id != tempId).toList(),
);
결론
낙관적 업데이트 패턴으로 만들면 서버 응답을 기다리는 동안에도 사용자 경험이 매끄럽게 유지되도록 도와준다.
'Developments > Flutter' 카테고리의 다른 글
[Flutter] 3.7 업데이트 살펴보기 (2) (0) | 2025.02.13 |
---|---|
[Flutter] 3.7 업데이트 살펴보기 (1) (0) | 2025.02.11 |
[Flutter/M4] Java version & Gradle 호환성 맞춰서 앱 빌드하기 (0) | 2025.01.14 |
[Flutter] Sliver, Slivers, SliverList 개념 알아보기 (0) | 2024.12.11 |
[Flutter] @JsonSerializable()와 @JsonKey 사용법 (0) | 2024.12.03 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 오블완
- ios
- flutter3.7
- lints
- 다트문법
- swiftmigration
- llm 설치
- 낙관적 업데이트 패턴
- 티스토리챌린지
- sliver
- 플러터ios애니메이션
- jsonserializable
- jsonkey
- flutter
- 플러터업데이트
- flutter_lints
- flutter 3.7
- flutter updates
- 플러터 업데이트
- 렌더링최적화
- 플러터네이티브
- tojson()
- sliverlist
- SWIFT
- slivers
- fromjson()
- 개발신입
- analysis_options
- 플러터
- 오블완챌린지
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
글 보관함