-
같은 상태를 두 곳에서 쓰면 둘 중 하나가 거짓말합니다AI Agent/flutter 2026. 7. 7. 15:00728x90반응형

목록은 12, 상세는 11이던 좋아요 숫자 "목록에서는 좋아요가 12개인데, 상세로 들어가면 11개로 보여요." 아침에 열어 본 제보에는 스크린샷 두 장이 나란히 붙어 있었습니다.
같은 게시물, 같은 계정, 다른 숫자.
목록 카드의 하트 옆에는 12, 상세 화면 상단에는 11.
처음엔 별거 아니라고 생각했습니다.
캐시가 잠깐 엉킨 거겠거니 하고 상세에서 아래로 당겨 새로고침을 했는데, 상세만 12로 바뀌고 목록은 11에서 꿈쩍도 하지 않았습니다.
반대로 목록을 새로고침하면 이번엔 목록만 따라오고 상세가 뒤처졌습니다.그때 등이 살짝 서늘해졌습니다.
어느 쪽을 새로고침하든 나머지 하나가 늘 뒤처진다는 건, 캐시가 엉킨 게 아니라 이 숫자의 주인이 둘이라는 신호였거든요.
이건 상태관리 패키지를 무엇으로 고르느냐의 문제가 아니었습니다.
같은 의미의 값을 두 곳에서 각자 들고 있으면, 어느 쪽이 진짜인지 앱이 스스로 정하지 못한다는 문제였습니다.
저는 이걸 좋아요 카운트 하나로 배웠습니다.처음엔 동기화 코드를 더 넣으려고 했습니다
부끄럽지만 첫 삽질은 엉뚱한 데로 갔습니다.
목록과 상세가 안 맞으니, 상세에서 좋아요를 누를 때 목록 provider도 같이 갱신하라고 콜백을 하나 달았습니다.
그 화면만 놓고 보면 맞아 보였습니다.
그런데 목록에서 바로 좋아요를 누르는 경로, 푸시 알림을 눌러 상세로 곧장 들어오는 경로, 프로필에서 같은 글로 진입하는 경로까지 떠올리니 갱신해야 할 자리가 자꾸 늘어났습니다.
손으로 맞추는 동기화는 화면이 하나 늘 때마다 빚이 되는 구조였습니다.
삼십 분쯤 그러다가 방향이 틀렸다는 걸 인정했습니다.왜 두 화면이 서로 다른 숫자를 우겼을까요
콜백을 걷어내고, 두 provider에 각각 로그를 심어 봤습니다.
그러자 그림이 선명해졌습니다.
목록이 들고 있던 값은 앱을 처음 켰을 때 피드를 한 번 받아온 그 값 그대로였습니다.
상세는 화면에 들어갈 때마다 API를 새로 호출해 최신 값을 받아왔고요.
좋아요 버튼은 상세 화면에만 있었으니, 누르면 상세 쪽 숫자만 올라갔습니다.
목록으로 돌아가면 처음 받아둔 옛날 값이 그대로 앉아 있었습니다.두 provider는 서로의 존재를 몰랐습니다.
같은 게시물을 그리면서도 각자likeCount를 따로 기억하고 있었던 거죠.// 목록도 상세도 각자 likeCount를 들고 있으면, 누르는 순간 둘이 갈라집니다. final feedProvider = StateProvider<List<Post>>((ref) => []); // Post.likeCount final postDetailProvider = FutureProvider.family<Post, String>( // 또 Post.likeCount (ref, id) => api.fetchPost(id), );말로 풀면 당연한데, 화면에서는 그냥 "숫자가 안 맞는다"로만 보였습니다.
사용자는 provider 이름을 보지 않으니까요.
눈에 보이는 건 어긋난 두 숫자뿐입니다.
그래서 처음엔 저도 애먼 렌더링을 의심했습니다.좋아요의 주인을 한 곳으로 옮기고 나서
방향을 바꾼 뒤의 고침은 오히려 간단했습니다.
좋아요 카운트의 주인을 한 곳으로 정하는 것.
게시물 하나하나를 id로 들고 있는 store를 진짜 주인으로 두고, 목록과 상세는 둘 다 그 store에서 같은 항목을 읽기만 하게 했습니다.final postProvider = StateNotifierProvider<PostStore, Map<String, Post>>((ref) => PostStore()); // 목록도 상세도 postProvider의 같은 항목을 읽는다. 좋아요는 여기 한 곳만 갱신한다.좋아요를 누르면 이 store 한 곳을 갱신하고, 두 화면은 같은 값을 바라보니 어긋날 틈이 없어졌습니다.
신기하게도 코드가 늘지 않았습니다.
상세에서 따로 카운트를 챙기던 코드와, 아까 급하게 달았던 동기화 콜백이 같이 사라져서 오히려 줄었습니다.
화면을 억지로 맞추려던 코드가, 값의 주인을 정하고 나니 통째로 필요 없어진 겁니다.다만 대가가 아주 없지는 않았습니다.
이제 목록도 상세도 이 store를 거쳐 값을 읽으니, 처음 진입할 때 store에 게시물을 채워 넣는 흐름을 한 번 정리해야 했습니다.
그래도 값이 두 군데서 갈라질 걱정을 안 해도 된다는 게, 그 정리보다 훨씬 크게 남았습니다.이제는 숫자가 둘로 보이면 먼저 의심합니다
그 뒤로 화면 어딘가에서 같은 값이 두 번 그려지는 걸 보면, 위젯을 고치기 전에 이 값의 주인이 누구인지부터 묻게 됐습니다.
좋아요든 안 읽은 알림 수든 장바구니 개수든, 두 곳에서 각자 세고 있으면 둘 중 하나는 언젠가 거짓말을 합니다.
그리고 그 거짓말은 꼭 사용자가 먼저 발견해서 제보로 돌아옵니다.
실제로 얼마 뒤 안 읽은 알림 배지에서 같은 냄새를 한 번 더 맡았는데, 이번엔 위젯을 열기 전에 그 숫자의 주인부터 찾았습니다.아직도 매번 헷갈리긴 합니다.
서버가 주인인지, 화면이 주인인지, 잠깐 화면 안에서만 살다 사라져도 되는 값인지.
경계가 애매한 값도 많고요.
다만 이제는 그 질문을 버그가 터진 다음이 아니라 provider를 만들기 전에 던지려고 합니다.
다음 좋아요 숫자만큼은 한 군데서만 세고 싶어서요.원문 기준
원문 기준: https://docs.flutter.dev/data-and-backend/state-mgmt/intro
원문 본 날짜: 2026-07-01.
728x90반응형'AI Agent > flutter' 카테고리의 다른 글
보인다는 말보다 캡처 파일이 더 강합니다 (0) 2026.07.08 골든 테스트 PASS가 실제 화면 증거는 아닙니다 (0) 2026.07.07 Flutter는 widget을 그리는 게 아니라 element/render tree를 갱신합니다 (1) 2026.07.07 post-frame, microtask, animation tick은 같은 큐가 아닙니다 (0) 2026.07.06 Riverpod 3에서 await 중 ref가 죽는 순간 (0) 2026.07.06