[svelte-query] A result key first read after the query settled stays stale: the component's copy refreshes only on a change of an already-tracked key

Đang mở
#12,485 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@lazerg đang làm issue này rồi.

Từ ngày 1/11/2026.

  • #12487 của @lazerg — đang mở

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
20/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Đình trệ
Công nghệ
typescript
Lĩnh vực
frontend

Hướng nghiên cứu

Start with observer.trackResult(result) in createBaseQuery.svelte.js around line 29, then the #trackedProps check in queryObserver.js around lines 395-403, and the onPropTracked hook. Check the linked pull request #12487 first, since it already targets this bug. Done means the minimal case shows a b after about 300 ms, with a test that reads a key for the first time after the query has settled.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Versions: @tanstack/svelte-query 6.3.1, @tanstack/query-core 5.104.1, Svelte 5.

What happens

When notifyOnChangeProps is unset, createBaseQuery wraps the result in observer.trackResult(result) (createBaseQuery.svelte.js:29). QueryObserver.updateResult then notifies only when a key in #trackedProps changes (queryObserver.js:395-403).

The observer does add a key to its tracked set when a template first reads it. But the component's reactive copy is updated only through those notifications. If a query settles while the template has read only some of its keys, the update is skipped and the component keeps its copy of the old result. A key that the template reads later is then read from that stale copy, and nothing updates it again, because the query has already settled.

Minimal case

<script lang="ts">
  import { createQuery } from '@tanstack/svelte-query';

  const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
  const a = createQuery(() => ({ queryKey: ['a'], queryFn: () => wait(300).then(() => 'a') }));
  const b = createQuery(() => ({ queryKey: ['b'], queryFn: () => Promise.resolve('b') }));
</script>

{#if a.isError || b.isError}
  <p>error</p>
{:else if a.data === undefined || b.data === undefined}
  <p>loading</p>
{:else}
  <p>{a.data} {b.data}</p>
{/if}

Expected: a b after about 300 ms.

Actual: loading stays forever. b settles first, while the template has read only b.isError, because the || short-circuits before b.data. The change to b.data doesn't notify, so the component's copy of b keeps data: undefined. When a settles, the template reads b.data from that stale copy.

Workaround

Set notifyOnChangeProps: 'all' in the client's default query options, or read every key before branching.

Suggestion

Pass onPropTracked to trackResult and refresh the component's copy when a key is first tracked, or skip tracking in the Svelte adapter, since Svelte already re-renders key by key.

Ngôn ngữ chính
TypeScript
Star
50.5k
Fork
4.2k
Merge trung bình
11 giờ 6 phút
Pull request đã merge (30 ngày)
492

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của TanStack/query

Tất cả issue của TanStack/query

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.