[2.0] Event handlers fired synchronously from an effect (focus(), showModal()) inherit the effect's strict-read window
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 44/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- javascript, typescript
調査の方向性
Start by tracing how Solid delegates DOM event handlers and manages strict-read and effect-callback state when native calls such as focus() dispatch events synchronously. Add or locate a regression test for an effect-triggered focus event whose handler reads a prop, and check the dialog showModal()/close() cases described here. Done means these handlers run with a clean reactive state, without the strict-read warning or effect-callback phase.
索引モデルが issue の本文から書いたものです。
説明
Version: solid-js / @solidjs/web / @solidjs/signals 2.0.0-rc.15 (the rc.16 and rc.17 changelogs don't mention it)
What happens
A native DOM call that fires events synchronously — el.focus(), dialog.showModal(), dialog.close() — made from the apply half of an effect runs the delegated handlers inside that effect callback. A handler that reads a prop (a normal thing for an event handler to do) then logs [STRICT_READ_UNTRACKED] in dev, as if the read happened in the effect body.
import { createEffect, createSignal } from 'solid-js'
function Field(props: { label: string }) {
return <input onFocus={() => console.log('focused', props.label)} />
}
export function App() {
const [open, setOpen] = createSignal(false)
let box!: HTMLDivElement
createEffect(open, (isOpen) => {
if (isOpen) box.querySelector('input')!.focus() // handler runs here
})
return (
<div ref={box}>
<Field label="Name" />
<button onClick={() => setOpen(true)}>Edit</button>
</div>
)
}
Click "Edit": the focus moves from the effect, onFocus reads props.label, and dev logs [STRICT_READ_UNTRACKED]. Focusing the same input with the mouse logs nothing.
Same with a <dialog> opened with showModal() from an effect: the focus it moves inside and the focus it gives back on close() both fire focus/blur handlers inside the effect callback.
Expected
An event handler runs from a clean reactive state no matter what dispatched the event: no strict-read window and not in the effect-callback phase, the same as for a user's own event. The handler is a one-time snapshot by nature; where the dispatch came from shouldn't change that.
Workaround
We wrap each such native call in untrack(() => el.focus()), which ends the strict-read window for the handlers it fires (the effect-callback phase itself stays, so a computation created in such a handler has no owner).
- 主要言語
- TypeScript
- スター
- 36.2k
- フォーク
- 1.1k
- 平均マージ
- 10時間 38分
- マージ済み PR(30日)
- 352
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
solidjs/solid のほかの issue
-
`lazy()`: remounting an already-loaded component renders empty (or the Suspense fallback) since 1.9.14対応中かも @itisrmk が 6 日前に担当しました。 オープン1.x
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 52/100
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
solidjs/solid#4242 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 53/100
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 1〜2日 初心者へのやさしさ 58/100
メンテナーはふだん 1 日以内に返信
似ている issue
-
難易度 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
-
Snapshot capture failure (EPERM spawning git) fails the whole step despite the best-effort contractオープンreproduced
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
anomalyco/opencode#58685 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信