Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- Clean Architecture
- riverpod
- scss
- java 콘솔 출력 차이
- LLM
- printf
- nodejs
- 앱심사
- java 출력
- react
- JS
- 자바스크립트
- DART
- 단축키
- Flutter
- java
- npm
- 자바 출력 방식
- unity
- UI/UX
- lifecycle
- JQ
- 배포
- firebase
- develop
- 자바 포맷 출력
- abap
- 엡
- println
- ListView
Archives
- Today
- Total
guricode
Riverpod ref.listen 라이프사이클 에러 트러블슈팅 본문
코드를 짜다 보니 ref.listen을 initState() 안에 넣어뒀는데, 이게 문제였다.
ref.listen은 Riverpod이 위젯을 빌드하는 중에만 호출할 수 있는데,
initState()는 위젯이 아직 빌드 트리에 올라가기 전이라 Provider랑 연결이 안 돼 있다.
그래서 실행하자마자 아래 오류가 터졌다.
ref.listen can only be used within the build method of a ConsumerWidget
Failed assertion: 'debugDoingBuild'
결국 정리하자면
“빌드 전에 ref.listen을 불러서 Riverpod이 감시 대상을 찾을 수 없었던 것”
즉, 위젯이 완전히 만들어지기 전에 감시를 걸어서 생긴 구조적인 오류였다.
아래처럼 initState 안에서 ref.listen을 등록한 코드가 문제였다.
@override
void initState() {
super.initState();
// ❌ 빌드 전에 ref.listen 호출
ref.listen<CommunityCreateVm>(
communityCreateVmProvider,
(prev, next) {
// 상태 변경 시 동작
},
);
}
이 코드는 컴파일은 되지만 실행 도중 Flutter가
“아직 빌드 중이 아니야”라며 에러를 던진다.
해결 과정
ref.listen을 build() 안으로 옮기고,
UI 업데이트가 프레임 중에 일어나지 않도록
WidgetsBinding.instance.addPostFrameCallback으로 감쌌다.
이렇게 하면 위젯이 다 그려진 다음 컨트롤러나 선택 칩을 안전하게 갱신할 수 있다.
@override
Widget build(BuildContext context) {
// 빌드 중에 ref.listen 등록
ref.listen<CommunityCreateVm>(
communityCreateVmProvider,
(prev, next) {
if (next.isEdit && !next.loading) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (_titleController.text != next.title) {
_titleController.text = next.title;
}
if (_contentController.text != next.content) {
_contentController.text = next.content;
}
// 카테고리 칩도 같이 반영
ref.read(selectedCategoryCodeProvider.notifier).state =
next.categoryCode;
ref.read(selectedSubCategoryCodeProvider.notifier).state =
next.categoryDetailCode;
});
}
},
);
final st = ref.watch(communityCreateVmProvider);
return Scaffold(
appBar: AppBar(title: Text(st.isEdit ? '글 수정' : '글쓰기')),
body: TextField(controller: _titleController),
);
}
구분 잘못된 방식 수정한 방식
| 호출 위치 | initState() | build() 내부 |
| 호출 시점 | 위젯 초기화 중 | 위젯 빌드 중 |
| UI 반영 시점 | 즉시 반영 (충돌 위험) | addPostFrameCallback 으로 프레임 이후 반영 |
| 결과 | debugDoingBuild 에러 발생 | 정상 작동 및 상태 동기화 완료 |
결론적으로
ref.listen은 빌드 중에만 쓸 수 있고,
컨트롤러나 칩 같은 UI 요소는 프레임이 끝난 뒤에 반영해야 한다.
'앱 > Flutter&Dart' 카테고리의 다른 글
| [Flutter] GoRouter 라우터 정리 – push, go, pushReplacement 차이 (0) | 2025.10.10 |
|---|---|
| [Flutter] 글 수정 후 뒤로가기 했을 때 이전 글이 보이는 문제 해결기 (0) | 2025.10.09 |
| [트러블슈팅] iOS와 Android 동시 배포 완전 정리 (0) | 2025.10.08 |
| [flutter] 자취의 정석 -9: Firebase 서버시간을 한국시간(KST)으로 정확히 보여주기, FieldValue.serverTimestamp() UTC표준 변환, “N분 전” 구현 (0) | 2025.10.02 |
| [flutter]자취의 정석 -8 게시글, 댓글 페이지네이션 microtask (0) | 2025.10.02 |