[2.0 rc.15 + next] For row lifecycle cleanup inherits the list computation and halts on a shared-state write
Maintainer thường phản hồi trong vòng 1 ngày
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 51/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ệ
- javascript, typescript
Hướng nghiên cứu
Start with the cleanup disposal path in packages/signals/src/map.ts and the cleanup invocation in core/owner.ts; then run the linked conformance case 058 with TARGET=rc15 bun test ./findings/058-list-cleanup-write/repro.test.ts. Trace how the cleanup inherits its write context and compare the For and Show controls. Done means the For cleanup releases shared state without halting reactivity, while ordinary computation writes remain rejected.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
What happens
Removing a row from a keyed For runs that row's lifecycle cleanup under the list's owned computation. An ordinary setter from the cleanup throws REACTIVE_WRITE_IN_OWNED_SCOPE, followed by REACTIVITY_HALTED. The row remains mounted and subsequent list updates are ignored. The identical cleanup unmounted by Show succeeds.
This reproduces with the documented component lifecycle form, onSettled(() => () => setCount(n => n + 1)), and with low-level onCleanup. It uses no async source, router, external UI library, SSR or hydration.
Minimal shape
import { render } from '@solidjs/web';
import { createSignal, flush, For, onSettled } from 'solid-js';
const [rows, setRows] = createSignal([1, 2]);
const [count, setCount] = createSignal(0);
function Row() {
onSettled(() => () => setCount(n => n + 1));
return <i>row</i>;
}
render(() => <For each={rows()}>{() => <Row />}</For>, document.body);
flush();
setRows([2]);
flush(); // development: owned-write error, then reactivity halted
Expected: one row remains, the release count becomes 1, and a later append works. An internal control-flow computation should not become the lifecycle callback's write context.
Executable case and version evidence
Fixed conformance case 058, including source, desired-behavior assertions and Show/ownedWrite controls.
After its frozen install, run:
TARGET=rc15 bun test ./findings/058-list-cleanup-write/repro.test.ts
- Published core/web/signals/compiler
2.0.0-rc.15(4937f0a2bfddd45a65738c189075aff577530073): both For cleanup variants fail in development; Show and ownedWrite controls pass. - Source-built current
nextat2172a37687e92dd91758476423f08cb4a12bcb0c: the same development failure. - Current HEAD production: the disposal/control cases pass because the owned-write guard is development-only. This report does not claim a production crash.
- Real system Google Chrome; native compiler; plain public JSX with no type bypass.
Raw versioned receipts and logs.
Source boundary and candidate repair
packages/signals/src/map.ts disposes removed row owners inside the list recomputation. core/owner.ts calls registered cleanups and final effect-returned cleanups directly, inheriting that ambient context. The setter guard then treats the cleanup as a computation write.
A local source experiment runs just the actual cleanup callbacks through runWithOwner(null, callback), restoring the caller's context/tracking afterward. It does not relax the setter guard or add a disposal-depth exemption. The original browser repro becomes green; ordinary computation writes and a computation nested inside cleanup remain rejected. Using the same Node/Vitest 4.1.6 runner, the upstream signals suite is 323 files / 5387 passes / 3 expected failures / 2 skips before and after. This is a tested direction, not a claim that the repair is upstream-reviewed.
Dedupe and application impact
Searched open and closed issues in solid, solid-router and solid-start. #4089 is cleanup rejoining an already-landed transaction; #3601 is reentrant double cleanup. This case needs neither a transaction nor reentrant disposal.
The real application trigger was deleting a row from its own open menu: dismissable-layer teardown publishes shared state to still-mounted UI. It currently requires deferred writes or ownedWrite declarations in library internals merely to survive list removal.
- Ngôn ngữ chính
- TypeScript
- Star
- 36.1k
- Fork
- 1.1k
- Merge trung bình
- 11 giờ 37 phút
- Pull request đã merge (30 ngày)
- 344
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- 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/solid
-
`lazy()`: remounting an already-loaded component renders empty (or the Suspense fallback) since 1.9.14Có thể đã có người làm @itisrmk đã nhận 3 ngày trước. Đang mở1.x
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 1-2 ngày Mức phù hợp với người mới 48/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 35/100
Maintainer thường phản hồi trong vòng 1 ngày
-
`createRoot`'s dispose function keeps `fn` alive, so `<For>`/`<Index>` rows retain removed list itemsCó thể đã có người làm @boombang đã nhận 5 ngày trước. Đang mở1.x
Độ khó 4/5 1-2 ngày Mức phù hợp với người mới 45/100
Maintainer thường phản hồi trong vòng 1 ngày
-
signals: a landing reveals a held write its stale reader re-derives onto a new flight (U-5, D-9)Đang mở
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 12/100
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của solidjs/solid
Issue tương tự
-
Sequências em espanhol: «Atualizado em», a aba «Fila» e o valor 'pause' ainda saem em portuguêsĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 77/100
melgarafael/DeskcommCRM#3104 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 1 ngày
-
🐛 [Bug] Mobile: on the login and registration pages the footer sits below the visible screenĐang mởbug service: webapp
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Ocelot-Social-Community/Ocelot-Social#10684 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
nicobailon/pi-subagents#2978 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 66/100
getsentry/sentry-conventions#732 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày