useSyncExternalStore does not bail out when the snapshot returns to the committed value: inline ref writing to a store loops forever (0.2.6)
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 55/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- react, typescript, vite
- Ambito
- frontend
Direzione di ricerca
Start with the reproduction in app.jsx and build it with and without the Redact plugin using vite build. Trace how Redact handles useSyncExternalStore when a render returns to the committed snapshot; done means the inline ref no longer causes repeated commits and the render bails out when the snapshot is unchanged.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
What happens
A component that reads a value with useSyncExternalStore and passes an inline ref callback that writes its node into the same store never settles under Redact. On every commit the old ref is called with null and the new ref with the node, so the store goes node → null → node and ends where it started. React re-renders, sees the snapshot equals the committed value, bails out (the new output and its new inline ref are discarded) and stops. Redact re-renders, commits the new inline ref, and the cycle repeats.
- React 19: 3 renders, input mounted, no errors.
- Redact 0.2.6, production build, Chromium 151 (Playwright, bundled headless): the main thread never yields;
page.gototimes out after 30 s. - Redact 0.2.6 in Vitest/jsdom (dev build):
flushPending exceeded 50 iterations — suspected infinite update loop.
Inline ref callbacks are allowed in React, and this store-plus-ref shape is common in component libraries. We first hit it through Base UI's Combobox input (its setInputElement writes the input into the component store), where a parent passed an inline ref.
Reproduction
index.html
<!doctype html><html><body><div id="root"></div><script type="module" src="./app.jsx"></script></body></html>
app.jsx
import { useSyncExternalStore } from 'react';
import { createRoot } from 'react-dom/client';
let value = null;
const listeners = new Set();
window.renders = 0;
const store = {
get: () => value,
set(next) { if (next !== value) { value = next; listeners.forEach((l) => l()); } },
subscribe(l) { listeners.add(l); return () => listeners.delete(l); },
};
function Field() {
window.renders++;
const el = useSyncExternalStore(store.subscribe, store.get);
return <input data-has-el={String(el != null)} ref={(node) => store.set(node)} />;
}
createRoot(document.getElementById('root')).render(<Field />);
Build with vite build with and without the redact() plugin (plus @vitejs/plugin-react) and open the result.
Expected
Like React: when a useSyncExternalStore re-render produces a snapshot equal to the one already committed (Object.is) and nothing else changed, bail out of that render instead of committing it.
Workaround on our side: give the input a stable useCallback ref.
- Lingua principale
- TypeScript
- Stelle
- 537
- Fork
- 22
- Merge medio
- 11h 37m
- PR unite (30g)
- 35
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di TanStack/redact
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
TanStack/redact#142 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 55/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di TanStack/redact
Issue simili
-
bug module:nodes tests
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
rocketride-org/rocketride-server#3020 ·
I maintainer di solito rispondono entro 2 giorni
-
area: dashboard area: tests good first issue size: XS tests
Difficoltà 1/5 1-3 ore Idoneità per principianti 88/100
I maintainer di solito rispondono entro 1 giorno
-
Read canvas commentsApertaenhancement needs-community-review
Difficoltà 2/5 1-3 ore Idoneità per principianti 67/100
shaharia-lab/slackcli#501 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
[Bug] Pod detail shows CPU usage ten times too high, and throws on decimal memory suffixesForse già presa @RaphaelFakhri l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
I maintainer di solito rispondono entro 11 giorni
-
`package.json`: build tools listed as runtime dependencies, exact pins causing duplicate installsAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
themesberg/flowbite-vue#471 ·