createPresence effect reads and writes mountedItem (Solid 2 EFFECT_WRITES_OWN_SOURCE)
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 85/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- typescript
- Ambito
- frontend
Direzione di ricerca
Inizia da packages/presence/src/index.ts, intorno all’effect createPresence alle righe 161–174, e leggi come item() e isMounted() ne guidano gli aggiornamenti. L’issue propone una correzione con createEffect(compute, apply) e untrack(mountedItem). Riproduci il problema aprendo il pulsante nell’esempio fornito. Il lavoro è completato quando questa interazione non segnala più EFFECT_WRITES_OWN_SOURCE e il comportamento di uscita seguito dalla sostituzione rimane intatto.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Describe the bug
createPresence keeps the mounted item in sync with an effect that both reads mountedItem() and writes it with setMountedItem. On Solid 2 that is EFFECT_WRITES_OWN_SOURCE: the effect re-runs because of its own write, settles in two flushes, and the first frame renders the pre-write value.
mountedItem only needs to be sampled when item() or isMounted() changes. It should not be a tracked input of the effect that writes it.
This shows up when opening a Kobalte Popover (@kobalte/[email protected]). Popover calls createPresence(() => forceMount || isOpen() || undefined, { transitionDuration: 0 }). The dev console reports:
[EFFECT_WRITES_OWN_SOURCE] effect "effect" re-ran because of its own write: it wrote "signal", which fed back into its inputs. Two flushes to settle, and the screen rendered the pre-write value in between. The written value is a function of what the effect reads — compute it in a memo (or normalize where the source is written) instead of correcting it after the fact.
in <Popover> › effect
The same effect is in packages/presence/src/index.ts on main (1.0.0-next.4) and in the published 1.0.0-next.2 build. The published build already splits this into Solid 2's createEffect(compute, apply), but the compute still tracks mountedItem().
createEffect(() => {
if (mountedItem() !== item()) {
if (isMounted()) {
setShouldBeMounted(false);
} else if (itemShouldBeMounted(item())) {
setMountedItem(() => item());
setShouldBeMounted(true);
}
} else if (!itemShouldBeMounted(item())) {
setShouldBeMounted(false);
} else if (itemShouldBeMounted(item())) {
setShouldBeMounted(true);
}
});
Suggested repair
Track item() and isMounted() only. Read the previous item with untrack(mountedItem) in the apply. Exit-then-swap stays: a change while still mounted only calls setShouldBeMounted(false); the swap still runs on the later pass, because that pass is driven by isMounted() becoming false, not by the mountedItem write.
createEffect(
() => [item(), isMounted()] as const,
([currentItem, isM]) => {
const mounted = untrack(mountedItem);
if (mounted !== currentItem) {
if (isM) setShouldBeMounted(false);
else if (itemShouldBeMounted(currentItem)) {
setMountedItem(() => currentItem);
setShouldBeMounted(true);
}
} else if (!itemShouldBeMounted(currentItem)) setShouldBeMounted(false);
else if (itemShouldBeMounted(currentItem)) setShouldBeMounted(true);
},
);
Reproduction
import { createSignal } from "solid-js";
import { createPresence } from "@solid-primitives/presence";
export default function App() {
const [open, setOpen] = createSignal(false);
createPresence(open, { transitionDuration: 0 });
return <button onClick={() => setOpen(true)}>Open</button>;
}
Click Open. The dev console reports EFFECT_WRITES_OWN_SOURCE as above.
Versions
@solid-primitives/presence1.0.0-next.2(same effect onmain/1.0.0-next.4)solid-js2.0.0-rc.15@kobalte/core2.0.0-alpha.4(how we hit it; the bug is in presence)
- Lingua principale
- TypeScript
- Stelle
- 1.6k
- Fork
- 165
- Merge medio
- 1g 13h
- PR unite (30g)
- 15
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
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 solidjs-community/solid-primitives
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
solidjs-community/solid-primitives#1059 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
solidjs-community/solid-primitives#1055 ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
solidjs-community/solid-primitives#894 ·
I maintainer di solito rispondono entro 1 giorno
-
help wanted
Difficoltà 2/5 1-3 ore Idoneità per principianti 52/100
solidjs-community/solid-primitives#830 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
help wanted
Difficoltà 3/5 1-2 giorni Idoneità per principianti 48/100
solidjs-community/solid-primitives#806 · 1 commento · 2 reazioni ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di solidjs-community/solid-primitives
Issue simili
-
bug hacktoberfest help wanted
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
libredb/libredb-studio#1941 ·
I maintainer di solito rispondono entro 1 giorno
-
chore other
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
alastair-smith/card-games#308 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 86/100
paperclipai/paperclip#17379 ·
I maintainer di solito rispondono entro 1 giorno
-
[good first issue, hacktoberfest] 🏯 Hacktoberfest Task - Add new Anime Quote 626 (good-first-issue)Apertacommunity first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 76/100
lingdojo/kana-dojo#33040 · 1 commento · 5 reazioni ·
I maintainer di solito rispondono entro 1 giorno
-
bug mobile ui
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
I maintainer di solito rispondono entro 1 giorno