useLiveInfiniteQuery commits an empty first render over a synchronously loaded collection (useLiveQuery doesn't)
Maintainer thường phản hồi trong vòng 1 ngày
Đá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
- 72/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- react, typescript
- Lĩnh vực
- frontend
Hướng nghiên cứu
Start at the useLiveInfiniteQuery hook and compare its collection startup and gcTime behavior with useLiveQuery. Add coverage to the existing hook tests for the synchronous eager-collection reproduction and check StrictMode and abandoned renders. Done means the infinite query has ready data on its first render without leaving sync running for an uncommitted render.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Describe the bug
With an eager, synchronously loaded collection, useLiveInfiniteQuery commits status: idle, data: [] on the first render and only has rows on the second commit. useLiveQuery over the same query with .limit(pageSize) has the rows on its first render.
In our app this shows up as a route that reads "no events" from the first commit and redirects away before the real data lands.
Cause: since #1675 the hook builds its collection with startSync: false ("Synchronization starts only when useSyncExternalStore commits the controller subscription"), so nothing can be published into the first render. useLiveQuery starts sync during render and relies on gcTime to reclaim a collection whose render never commits.
#1894 / #1896 fixed the db side of this for ordered windows over eager sources, so the remaining gap is the React hook only.
To reproduce
import { act, render } from "@testing-library/react"
import { createCollection, localOnlyCollectionOptions } from "@tanstack/db"
import { useLiveInfiniteQuery, useLiveQuery } from "@tanstack/react-db"
const events = createCollection(
localOnlyCollectionOptions({
id: `events`,
getKey: (e: { id: number; n: number }) => e.id,
initialData: Array.from({ length: 20 }, (_, i) => ({ id: i, n: i })),
})
)
const infinite: string[] = []
const plain: string[] = []
function Infinite() {
const r = useLiveInfiniteQuery(
(q) => q.from({ e: events }).orderBy(({ e }) => e.n),
{ pageSize: 10 }
)
infinite.push(`${r.status} ${r.data.length}`)
return null
}
function Plain() {
const r = useLiveQuery({
query: (q) => q.from({ e: events }).orderBy(({ e }) => e.n).limit(10),
})
plain.push(`${r.status} ${r.data.length}`)
return null
}
await act(async () => { render(<Infinite />) })
await act(async () => { render(<Plain />) })
console.log(infinite, plain)
Observed (status and data length per render)
useLiveInfiniteQuery [ 'idle 0', 'ready 10' ]
useLiveQuery [ 'ready 10' ]
Expected
useLiveInfiniteQuery [ 'ready 10' ]
Proposed fix
I'd rather not just flip it to startSync: true. My reading of #1675 is that it went to false so a render that never commits doesn't leave a started sync behind. useLiveQuery already handles that case: it starts sync during render with gcTime: 1, and a collection nobody subscribes to is cleaned up after that. The infinite hook already passes the same gcTime (DEFAULT_GC_TIME_MS), so it could start sync in render the same way and let gc reclaim abandoned ones. I tried flipping startSync to true in the built dist/esm/useLiveInfiniteQuery.js and the repro above logs [ 'ready 10' ]. I haven't run it under StrictMode or concurrent abandoned renders, so that part needs checking against the existing hook tests.
Happy to open a PR if that direction is fine.
Versions
- @tanstack/react-db 0.5.3
- @tanstack/db 0.11.3
- react / react-dom 19.3.0
- vitest 5.0.3, jsdom, @testing-library/react 16.3.3
- Ngôn ngữ chính
- TypeScript
- Star
- 3.9k
- Fork
- 268
- Merge trung bình
- 1 ngày 2 giờ
- Pull request đã merge (30 ngày)
- 206
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- 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.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của TanStack/db
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 45/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Reusable queries: standalone descriptor resolution and nested alias composition limitsCó thể đã có người làm @KyleAMathews đã nhận 1 ngày trước. Đang mở
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 1 ngày
-
electric-db-collection: on-demand + persistence fails after relaunch with "Snapshot requests are not supported in full mode"Có thể đã có người làm @KyleAMathews đã nhận 1 ngày trước. Đang mở
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 68/100
TanStack/db#2056 · 1 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 48/100
TanStack/db#1972 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Issue tương tự
-
Flaky: mongodb-memory-server 'Port already in use' when another process starts a mongod concurrentlyĐang mởarea:testing bug effort:S priority:P2
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
Maintainer thường phản hồi trong vòng 1 ngày
-
lens:agent lens:process process
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
thebristolsound/birdbrain#1772 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug priority:low ready-for-dev
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
Automattic/data-liberation-agent#685 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Business
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 66/100
Maintainer thường phản hồi trong vòng 1 ngày