createPresence effect reads and writes mountedItem (Solid 2 EFFECT_WRITES_OWN_SOURCE)
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 85/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- typescript
- Lĩnh vực
- frontend
Hướng nghiên cứu
Bắt đầu tại packages/presence/src/index.ts, quanh effect createPresence ở dòng 161–174, và đọc cách item() cùng isMounted() điều khiển các lần cập nhật. Issue đề xuất cách sửa bằng createEffect(compute, apply) và untrack(mountedItem). Tái hiện bằng cách mở nút trong ví dụ được cung cấp. Hoàn tất khi thao tác đó không còn báo EFFECT_WRITES_OWN_SOURCE và hành vi thoát rồi mới chuyển đổi vẫn được giữ nguyên.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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)
- Ngôn ngữ chính
- TypeScript
- Star
- 1.6k
- Fork
- 165
- Merge trung bình
- 1 ngày 13 giờ
- Pull request đã merge (30 ngày)
- 15
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của solidjs-community/solid-primitives
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
solidjs-community/solid-primitives#1059 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 48/100
solidjs-community/solid-primitives#1055 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 48/100
solidjs-community/solid-primitives#894 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
help wanted
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 52/100
solidjs-community/solid-primitives#830 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
help wanted
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 48/100
solidjs-community/solid-primitives#806 · 1 bình luận · 2 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của solidjs-community/solid-primitives
Issue tương tự
-
area: image-engine bug priority: low
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
snapotter-hq/SnapOtter#3885 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Mend: dependency security vulnerability
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Maintainer thường phản hồi trong vòng 3 ngày
-
pending triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug P3 UI/UX
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Maintainer thường phản hồi trong vòng 1 ngày
-
clawsweeper:fix-shape-clear clawsweeper:queueable-fix clawsweeper:source-repro impact:ux-friction issue-rating: 🦞 diamond lobster no-stale P3
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 73/100
openclaw/openclaw#182077 · 1 bình luận · 1 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày