Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

createPresence effect reads and writes mountedItem (Solid 2 EFFECT_WRITES_OWN_SOURCE)

Aperta Adatta ai principianti
#1,082 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

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/presence 1.0.0-next.2 (same effect on main / 1.0.0-next.4)
  • solid-js 2.0.0-rc.15
  • @kobalte/core 2.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

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di solidjs-community/solid-primitives

Tutte le issue di solidjs-community/solid-primitives

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.