2.0.0-rc.20: <Loading> stays on its fallback forever when an async memo's first answer is superseded while a sibling under the same boundary refetches
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 25/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- typescript
- Área
- frontend
Línea de trabajo
Start by running the reproduction as a Vitest test with jsdom, and confirm that the control case passes while the sibling-refetch case shows <p>wait</p>. The bug sits in how a Loading boundary tracks pending async memos when a first promise is superseded by a synchronous recomputation, so the fix lives in the reactive core, not in the components shown. Done means both cases in the repro render <i>B</i><b>A</b> and the boundary recovers after later writes.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Describe the bug
Two async memos a and b are read under one <Loading>. b is on its first load. While it loads, a starts a refetch (returns a new promise). b's first answer then lands in the order data libraries use: the value is stored and the memo's source is bumped before the first promise's continuation reaches the core, so the first flight is superseded by a synchronous recomputation. a's refetch then settles.
Both memos now hold settled values, but <Loading> shows its fallback forever. Without the sibling refetch the same sequence renders the content.
- rc.13: renders
""(also wrong) - rc.20:
<p>wait</p>forever - next@215c365:
<p>wait</p>forever
Steps to Reproduce
Same setup as above. repro.test.tsx:
import { render } from "@solidjs/web";
import { createMemo, createSignal, Loading, Show } from "solid-js";
import { expect, it } from "vitest";
const wait = (ms: number) => new Promise((r) => setTimeout(r, ms));
async function run(refetchA: boolean): Promise<string> {
const [aVersion, setAVersion] = createSignal(0);
const [bVersion, setBVersion] = createSignal(0);
let aFlight: Promise<string> | null = null;
let releaseA: (v: string) => void = () => {};
let bValue: string | null = null;
let releaseB: (v: string) => void = () => {};
const bFlight = new Promise<string>((resolve) => (releaseB = resolve));
const el = document.createElement("div");
const dispose = render(() => {
const a = createMemo(() => (aVersion(), aFlight ?? "A"));
const b = createMemo(() => (bVersion(), bValue ?? bFlight.then((v) => v)));
return (
<Loading fallback={<p>wait</p>}>
<Show when={b()}>
<i>{b()}</i>
</Show>
<Show when={a()}>
<b>{a()}</b>
</Show>
</Loading>
);
}, el);
await wait(10);
expect(el.innerHTML).toBe("<p>wait</p>");
if (refetchA) {
aFlight = new Promise<string>((resolve) => (releaseA = resolve));
setAVersion(1);
}
await wait(0);
// b's first answer: the value is written and its version bumped before the
// first promise's continuation reaches the core (the order TanStack Query uses).
bValue = "B";
releaseB("B");
setBVersion(1);
await wait(20);
if (refetchA) {
aFlight = null;
releaseA("A");
setAVersion(2);
}
await wait(50);
const html = el.innerHTML;
dispose();
return html;
}
it("control: without a sibling refetch the content renders", async () => {
expect(await run(false)).toBe("<i>B</i><b>A</b>");
});
it("with a sibling refetch in the same window the content renders once both settle", async () => {
expect(await run(true)).toBe("<i>B</i><b>A</b>");
});
package.json
{
"name": "solid-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"
},
"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
<i>B</i><b>A</b> in both cases.
Actual behavior
Control passes; with the sibling refetch the boundary stays at <p>wait</p> and never recovers (no further writes revive it).
Platform
As above.
- Lenguaje dominante
- TypeScript
- Estrellas
- 36.2k
- Forks
- 1.1k
- Merge medio
- 10 h 10 min
- PR fusionados (30 d)
- 505
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de solidjs/solid
-
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
Los mantenedores suelen responder en 1 día
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 22/100
Los mantenedores suelen responder en 1 día
-
What gets passed to the `when` prop of a `Show` still gets executed twice on SSRPosiblemente ocupada @brenelz la tomó hace 4 días. Abierto1.x
Dificultad 3/5 1-2 días Aptitud para principiantes 52/100
Los mantenedores suelen responder en 1 día
-
enhancement
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
solidjs/solid#4447 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
enhancement
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
Los mantenedores suelen responder en 1 día
Todos los issues de solidjs/solid
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 66/100
riverqueue/river#1576 ·
Los mantenedores suelen responder en 1 día
-
[bug] A prompt queued during a run is assessed without its textPosiblemente ocupada @jwiegley la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
DevMortimer/pi-warden#211 ·
Los mantenedores suelen responder en 1 día
-
enhancement
Dificultad 1/5 Menos de una hora Aptitud para principiantes 84/100
mattermost/compass-design#191 ·
Los mantenedores suelen responder en 1 día
-
Add unit tests for the organization admin role checkPosiblemente ocupada @SaffuSafwan la tomó hoy. Abiertoarea/core good first issue help wanted
Dificultad 1/5 Menos de una hora Aptitud para principiantes 90/100
elmohq/elmo#1095 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
HorusGoul/trizum#559 · 1 comentario ·
Los mantenedores suelen responder en 1 día