signals-flutter について
signals-flutterは、signals_flutterパッケージでFlutterのリアクティブなUIを構築するためのスキルです。リアクティブ状態のプリミティブ、非同期シグナル、コレクション、ウィジェット再構築の最適化、シグナル駆動の描画と副作用を解説します。
主な機能
- 01書き込み可能なシグナルと計算シグナルの作成
- 02effectによる依存関係の追跡
- 03再計算を抑える更新の一括処理
- 04リアクティブな非同期状態とコレクション
- 05SignalBuilderによる再構築範囲の限定
- 06SignalCustomPaintによるシグナル駆動の描画
活用シーン
- 01Flutterアプリのリアクティブ状態の設計
- 02非同期処理とシグナル状態の組み合わせ
- 03影響を受けるUIサブツリーだけの更新
- 04シグナルによる高頻度のカスタム描画
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ rodydavis/ signals.dart --skill signals-flutterインストール後、Claude Code で/signals-flutterを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
CONTEXT.mdasync/async_signal.mdcomputed_async.mdcomputed_from.mdCONTEXT.mdfuture_signal.mdstream_signal.mdcollections/CONTEXT.mditerable_signal.mdlist_signal.mdmap_signal.mdqueue_signal.mdset_signal.mdcore/batch.mdcomputed.mdCONTEXT.mdeffect.mdreadonly.mdsignal.mdextensions/CONTEXT.mdwatch.mdutils/connect.mdCONTEXT.mdlinked_signal.mdtimer_signal.mdtracked_signal.mdwidgets/CONTEXT.mdsignal_builder.mdsignal_custom_paint.mdsignal_effect.md詳細
Flutter Reactive Signals 連携
このスキルでは、signals_flutter パッケージを使用した Flutter UI バインディングの最適化、要素レベルのリアクティブな追跡、高頻度のレンダリングについて説明します。
関連ドキュメントと項目
コアプリミティブ
| 関連ファイル | 説明 |
|---|---|
| signal.md | 値アクセサー、変更の仕組み、基本的なカスタムオプションを備えた、標準的な書き込み可能なリアクティブ状態プリミティブです。 |
| computed.md | リアクティブな依存関係を動的に追跡する、遅延評価されるメモ化済みの読み取り専用派生状態シグナルです。 |
| effect.md | アクティブなサブスクリプションループ、動的な依存関係の更新、ライフサイクルの終了処理を管理する同期オブザーバーです。 |
| readonly.md | 一方向のデータアクセスフローを保証する読み取り専用シグナルビューです。 |
| batch.md | リアクティブな計算を最適化し、レンダリングや再計算の頻発を防ぐトランザクション形式の状態変更ブロックです。 |
非同期操作
| 関連ファイル | 説明 |
|---|---|
| future_signal.md | 二重評価の問題を解消する、単一評価の非同期 Future 状態表現です。 |
| stream_signal.md | 非同期の読み込み/データ/エラー状態に対応付ける、動的でライフサイクル安全な自己破棄型ストリームリスナーです。 |
| async_signal.md | 読み込み、成功データ、失敗エラーの状態を明確に対応付ける、統合された非同期状態コンテナーです。 |
| computed_async.md | アクティブな競合状態の保護機能を備え、リアクティブシグナル上に構築された合成可能な非同期操作です。 |
| computed_from.md | 複数の非同期シグナルを単一の統合結果にまとめる状態アグリゲーターシグナルです。 |
リアクティブコレクション
| 関連ファイル | 説明 |
|---|---|
| list_signal.md | 要素レベルのリアクティビティをサポートするため、標準操作をプロキシする最適化されたリストラッパーです。 |
| set_signal.md | 重複を無視し、一意な変更時に通知するカスタムセットラッパーです。 |
| map_signal.md | 辞書要素の検索を個別にトリガーできる、粒度の細かいマップラッパーです。 |
| iterable_signal.md | カスタムの遅延走査を動的なサブスクリプションレイヤーに対応付けるイテラブルラッパーです。 |
| queue_signal.md | 最適化されたリアクティブパイプライン構造をサポートする両端キューラッパーです。 |
ユーティリティプリミティブ
| 関連ファイル | 説明 |
|---|---|
| linked_signal.md | 手動でのオーバーライドのリセットとカスタム同値性チェックをサポートする、書き込み可能な計算済みシグナルです。 |
| tracked_signal.md | すぐに利用できる簡潔な元に戻す/やり直す機能を実現する状態履歴ラッパーです。 |
| timer_signal.md | 一時停止、再開、リセットの機能を内蔵した、定期的にイベントを発行するストップウォッチシグナルです。 |
| connect.md | 複数の外部データパイプラインから単一のターゲットにデータを送る動的イベントコネクターです。 |
Flutter ウィジェット
| 関連ファイル | 説明 |
|---|---|
| signal_builder.md | 名前付きの builder コールバックシグネチャを利用して、サブツリーを局所的に再構築するウィジェットです。 |
| signal_widget.md | SignalsMixin の非推奨化に対応する、コンポーネントレベルのリアクティブなステートレス/ステートフルウィジェットです。 |
| signal_effect.md | トリガーイベント(スナックバー、ダイアログ、ルートなど)を適切に処理する、レイアウト安全な副作用オーケストレーターです。 |
| signal_custom_paint.md | キャンバスの描画操作を回避し、120 FPS で動作する超高性能 GPU レンダーボックスです。 |
Flutter 拡張機能
| 関連ファイル | 説明 |
|---|---|
| watch.md | [非推奨] 従来のコンテキストレベルの watch 拡張機能です(SignalBuilder または SignalWidget の使用を推奨します)。 |
コアプリミティブ クイックスタートガイド
signals ライブラリは、あらゆるリアクティブなビジネスロジックをモデル化するための構成要素となる、5 つのコア関数を公開しています。
1. signal(initialValue)
新しいミュータブルなシグナルコンテナーを作成します。.value にアクセスすると、シグナルの値を読み取ったり、更新をサブスクライブしたりできます。
final counter = signal(0);
print(counter.value); // 0
counter.value = 1; // Mutates value and schedules dependent updates
.peek()
変更をサブスクライブせずに、シグナルの現在の値を読み取ります。
final counter = signal(0);
final logCount = signal(0);
effect(() {
print(counter.value);
// Read using peek to avoid subscribing/triggering loop
logCount.value = logCount.peek() + 1;
});
2. untracked(fn)
シグナルを読み取っても、どのシグナルにもサブスクライブしないコールバックを実行します。
final counter = signal(0);
final count = signal(0);
effect(() {
print(counter.value);
count.value = untracked(() => count.value + 1);
});
3. computed(fn)
複数のシグナルの値を組み合わせ、遅延評価されるメモ化済みの派生シグナルを作成します。
final first = signal('John');
final last = signal('Doe');
final fullName = computed(() => '${first.value} ${last.value}');
print(fullName.value); // John Doe
4. effect(fn)
コールバックを実行し、その中で読み取られたシグナルをサブスクライブすることで、即時の同期的な副作用を調整します。
final name = signal('Jane');
final dispose = effect(() => print('Hello $name'));
dispose(); // Clean up subscription
5. batch(fn)
複数のシグナルへの書き込みを単一のトランザクションにまとめ、依存するすべての computed の評価と effect を最後に一度だけ実行します。
final a = signal(0);
final b = signal(0);
batch(() {
a.value = 1;
b.value = 2;
});
1. ウィジェットの再構築の最適化
A. SignalBuilder(推奨)
局所的でコンテキストから分離されたウィジェットの再構築を実現します。レンダリングのパフォーマンスを最大限に高めるため、SignalBuilder でラップするのは可能な限り小さなウィジェットだけにしてください。
SignalBuilder(
builder: (context) => Text('Count: ${counter.value}'),
)
B. リアクティブコンポーネントウィジェット(SignalWidget / SignalStatefulWidget)
v7 では、SignalsMixin と BuildContext.watch(context) は非推奨であり、カスタム lint ルールによって警告が発生します。mixin やコンテキスト拡張の watch を使う代わりに、SignalWidget または SignalStatefulWidget を継承すると、標準的なウィジェットツリー内でリアクティブな追跡が自動的に、非常に効率よく行われます。
// Reactive Stateless Widget
class MyWidget extends SignalWidget {
const MyWidget({super.key});
@override
Widget build(BuildContext context) {
return Text('Count: ${counter.value}');
}
}
2. 高頻度レンダリング(SignalCustomPaint)
シグナルによって駆動される超高頻度の描画では、Flutter の負荷が高いウィジェットのレイアウト/再構築ライフサイクルを完全に迂回します。
SignalCustomPaint と SignalPainterWidget は、カスタムのプロキシレンダーボックス内で markNeedsPaint() を呼び出し、GPU に直接書き込みます。
SignalCustomPaint(
painter: MySignalPainter(progressSignal),
child: Container(),
)
3. ウィジェットツリー内の副作用(SignalEffect)
SignalEffect / SignalListener を使用すると、スナックバーの表示、ナビゲーション、モーダルの表示などの非同期の副作用を、ウィジェットのライフサイクル内で適切に実行できます。
SignalEffect(
callback: (context) {
if (errorMessage.value != null) {
showDialog(context: context, builder: (_) => Alert(errorMessage.value!));
}
},
child: ChildWidget(),
)