createPresence effect reads and writes mountedItem (Solid 2 EFFECT_WRITES_OWN_SOURCE)
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 新手友好度
- 85/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- typescript
- 领域
- frontend
调研方向
从 packages/presence/src/index.ts 第 161–174 行附近的 createPresence effect 开始,阅读 item() 和 isMounted() 如何驱动其更新。Issue 提供了使用 createEffect(compute, apply) 和 untrack(mountedItem) 的建议修复方案。在提供的示例中打开按钮以复现。完成的标准是该交互不再报告 EFFECT_WRITES_OWN_SOURCE,并且先退出再切换的行为保持不变。
由索引模型根据 Issue 内容生成。
描述
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)
- 主要语言
- TypeScript
- 星标
- 1.6k
- 派生
- 165
- 平均合并
- 12 小时 35 分钟
- 30 天内合并 PR
- 14
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
solidjs-community/solid-primitives 的其他 Issue
-
bug
难度 2/5 1-3 小时 新手友好度 72/100
solidjs-community/solid-primitives#1059 · 1 条评论 ·
维护者通常 1 天内回复
-
enhancement
难度 4/5 3-5 天 新手友好度 48/100
solidjs-community/solid-primitives#1055 ·
维护者通常 1 天内回复
-
enhancement
难度 4/5 3-5 天 新手友好度 48/100
solidjs-community/solid-primitives#894 ·
维护者通常 1 天内回复
-
help wanted
难度 2/5 1-3 小时 新手友好度 52/100
solidjs-community/solid-primitives#830 · 2 条评论 ·
维护者通常 1 天内回复
-
help wanted
难度 3/5 1-2 天 新手友好度 48/100
solidjs-community/solid-primitives#806 · 1 条评论 · 2 个 reaction ·
维护者通常 1 天内回复
查看 solidjs-community/solid-primitives 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 68/100
awesome-dsh-plugin/awesome-dsh-plugin#9184 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 75/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 85/100
farion1231/cc-switch#8829 ·
维护者通常 1 天内回复
-
[core-client] Remove unused hand-maintained transport helpers after the definition-table cutover未关闭doc-audit enhancement
难度 2/5 1-3 小时 新手友好度 88/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 85/100