solid-query 6.0.0-rc.5: useBaseQuery bumps its version signal on observerAdded/observerRemoved, remounting <Show> children in a loop on Solid 2 rc.14+

Đang mở Phù hợp với người mới
#12,466 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

Chưa có ai nhận issue này.

Đánh giá

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

Hướng nghiên cứu

Bắt đầu từ packages/solid-query/src/useBaseQuery.ts trên nhánh solid-query-v6-pre và kiểm tra onCacheEvent, đặc biệt là cách nó xử lý event.type. Thêm một test hồi quy dựa trên bước tái hiện để kiểm tra component con chỉ được mount một lần; hoàn thành khi các sự kiện chỉ liên quan đến observer không còn kích hoạt vòng lặp remount nữa.

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

Mô tả

Describe the bug

useBaseQuery's onCacheEvent (packages/solid-query/src/useBaseQuery.ts on solid-query-v6-pre) calls setVersion(v => v + 1) for every query-cache event whose queryHash matches, without looking at event.type. observerAdded, observerRemoved, observerOptionsUpdated and observerResultsUpdated do not change the query's state, but each one re-runs the result projection.

On Solid 2 rc.14+ this combines with a core issue (solidjs/solid#4540): a non-keyed <Show> gated on q.data remounts its children on every re-run. A child that calls useQuery with the same key adds an observer on mount → observerAdded → version bump → remount → new observer → … an infinite remount loop.

  • solid-js rc.13 + solid-query 6.0.0-rc.5: 1 mount
  • solid-js rc.20 + solid-query 6.0.0-rc.5: loop (21 mounts before the guard)
  • solid-js next@215c365: loop
Steps to Reproduce

package.json: solid-js, @solidjs/web, @solidjs/signals 2.0.0-rc.20, @tanstack/solid-query 6.0.0-rc.5; dev @solidjs/vite-plugin 3.0.0-next.54, vitest 5.0.5, jsdom 30.1.2.

import { render } from "@solidjs/web";
import { QueryClient, QueryClientProvider, useQuery } from "@tanstack/solid-query";
import { Show } from "solid-js";
import { expect, it } from "vitest";

const wait = (ms: number) => new Promise((r) => setTimeout(r, ms));

it("a second observer mounted under a Show gated on the first one's data mounts once", async () => {
  const client = new QueryClient({ defaultOptions: { queries: { retry: false, staleTime: Number.POSITIVE_INFINITY } } });
  let mounts = 0;
  const options = () => ({ queryKey: ["k"], queryFn: () => wait(10).then(() => 1) });
  function Child() {
    mounts++;
    if (mounts > 20) throw new Error("remount loop");
    useQuery(options);
    return <p>child</p>;
  }
  function Page() {
    const q = useQuery(options);
    return (
      <Show when={q.data !== undefined}>
        <Child />
      </Show>
    );
  }
  const el = document.createElement("div");
  const dispose = render(() => (
    <QueryClientProvider client={client}>
      <Page />
    </QueryClientProvider>
  ), el);
  await wait(100);
  dispose();
  expect(mounts).toBe(1);
});

package.json

{
  "name": "solid-query-repro",
  "private": true,
  "type": "module",
  "scripts": { "test": "vitest run" },
  "dependencies": {
    "solid-js": "2.0.0-rc.20",
    "@solidjs/web": "2.0.0-rc.20",
    "@solidjs/signals": "2.0.0-rc.20",
    "@tanstack/solid-query": "6.0.0-rc.5"
  },
  "devDependencies": {
    "@solidjs/vite-plugin": "3.0.0-next.54",
    "jsdom": "30.1.2",
    "vitest": "5.0.5"
  }
}

vitest.config.ts

import solid from "@solidjs/vite-plugin";
import { defineConfig } from "vitest/config";

export default defineConfig({
  plugins: [solid()],
  test: { environment: "jsdom" },
});
Expected behavior

Child mounts once.

Actual behavior

expected 21 to be 1 (the guard throws "remount loop").

Suggested fix

Bump version only for events that can change the result (added, removed, updated), not for observer* events. The core issue is the root cause; this avoids the trigger and an unnecessary projection re-run per observer mount/unmount.

Related: #11903, #12031 / #12034 (same function, different defects).

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

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.