solidjs-patterns について
OpenWorkのUIで使うSolidJSのパターンをまとめた開発スキルです。UIを保守する開発者向けに、細粒度のシグナルと操作ごとの非同期状態管理で状態結合による不具合を抑えます。
主な機能
- 01細粒度シグナルの優先
- 02操作ごとの保留状態管理
- 03createMemo()によるUI状態の導出
- 04シグナル値の不変更新
- 05await前のシグナル値スナップショット
活用シーン
- 01無関係な操作の相互無効化を防止
- 02並行する非同期処理の管理
- 03非同期ハンドラーの古い値参照を回避
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ different-ai/ openwork --skill solidjs-patternsインストール後、Claude Code で/solidjs-patternsを入力して読み込まれたか確認します。
詳細
このスキルが必要な理由
OpenWork の UI は SolidJS で構築されており、React のような再レンダリングではなく、シグナルによって更新されます。
多くの「UI が固まる」バグは、再レンダリングの問題ではなく、実際には状態の結合の問題です(例:1 つのグローバルな busy() が、関係のないアクションまで無効にする)。
このスキルでは、OpenWork で一貫して使用したいパターンをまとめています。
基本ルール
- 共有のグローバルフラグより、粒度の細かいシグナルを優先します。
- 非同期アクションは個別にスコープ化します(各アクションが独自の
pending状態を持ちます)。 - ブール値を重複して保持するのではなく、
createMemo()で UI の状態を導出します。 - シグナルに格納された配列やオブジェクトを変更しないでください。必ず新しい値を作成します。
スコープ化された非同期アクション(推奨)
(権限、インストール、バックグラウンド更新など)他の処理と重複する可能性がある操作では、グローバルな busy() を使い回さないでください。
アクションごとに専用のシグナルを使用します。
const [replying, setReplying] = createSignal(false);
async function respond() {
if (replying()) return;
setReplying(true);
try {
await doTheThing();
} finally {
setReplying(false);
}
}
理由
1 つの busy() ブール値はデッドロックを引き起こします。
- 時間のかかるタスクが
busy(true)を設定する - 権限のプロンプトが表示され、そのボタンが
busy()によって無効になる - 権限が許可されるまでタスクを続行できない
- ボタンが無効になっているため、ユーザーは許可できない
解決策:権限 UI は、権限専用の pending 状態によってのみ無効にする必要があります。
非同期ハンドラー内のシグナルのスナップショット
非同期関数内でシグナルを読み取り、安定した値が必要な場合は、早い段階でスナップショットを取得します。
const request = activePermission();
if (!request) return;
const requestID = request.id;
await respondPermission(requestID, "always");
UI 状態の導出
無効状態などの計算には、createMemo() を優先します。
const canSend = createMemo(() => prompt().trim().length > 0 && !busy());
リスト
- 導出した値を更新するには、セッターのコールバックを使用します。
setItems((current) => current.filter((x) => x.id !== id));
currentを直接変更しないでください。
実践的なチェックリスト(SolidJS の UI 変更)
- 長時間実行される処理中に true になる可能性があるグローバルフラグに依存するボタンはありますか?
- 2 つの非同期アクションが重複し、1 つのブール値を取り合う可能性はありますか?
- 重複している UI 状態はありますか(導出できる状態ではありませんか)?
- 値が変わっている可能性があるタイミングで、
awaitの後にイベントハンドラーがシグナルを読み取っていませんか? - props や型をリファクタリングした場合、中間にあるすべてのコンポーネントのシグネチャと呼び出し箇所も更新しましたか?
参考資料
- SolidJS:https://www.solidjs.com/docs/latest
- SolidJS のシグナル:https://www.solidjs.com/docs/latest/api#createsignal
- SolidJS のメモ:https://www.solidjs.com/docs/latest/api#creatememo
コメント
Markdown 対応