Agent Skills by ALSEL
Anthropic Claudeソフトウェア開発⭐ リポ 0品質スコア 50/100

react-flow-architecture

React Flowを使ったノードベースUIの構築に関するアーキテクチャ的なガイダンスを提供します。フローベースのアプリケーション設計、状態管理の意思決定、インテグレーションパターンの検討、またはReact Flowがユースケースに適しているかどうかの評価を行う際に活用してください。

description の原文を見る

Architectural guidance for building node-based UIs with React Flow. Use when designing flow-based applications, making decisions about state management, integration patterns, or evaluating whether React Flow fits a use case.

SKILL.md 本文

React Flow アーキテクチャ

React Flow の使用時期

適している場合

  • ビジュアルプログラミングインターフェース
  • ワークフロービルダーと自動化ツール
  • ダイアグラムエディタ (フローチャート、組織図)
  • データパイプラインの可視化
  • マインドマップツール
  • ノードベースのオーディオ/ビデオエディタ
  • デシジョンツリービルダー
  • ステートマシンデザイナー

代替案の検討

  • シンプルな静的ダイアグラム (SVG または canvas を直接使用)
  • 重いリアルタイムコラボレーション (カスタムシンク層が必要な場合がある)
  • 3D ビジュアライゼーション (Three.js、react-three-fiber を使用)
  • 10k 以上のノードのグラフ分析 (Sigma.js のような WebGL ベースのソリューションを使用)

デシジョンワークフロー (ゲート)

実装を開始またはスプリント計画を立てる前に、このシーケンスを実行します。使い捨てプロトタイプの場合のみスキップできます。

  1. インタラクションを命名する — トップユーザーアクション (例: ドラッグ、接続、削除、グループ化) をリストアップします。合格: 各アクションが実装する具体的な React Flow コールバック (onNodesChangeonConnect など) にマッピングされる。

  2. スケールを分類する — ピークノード数 (キャンバス表示またはドキュメント合計) を推定します。合格: あなたの範囲が Node Count Guidelines のいずれかの行に一致し、そのリストされた戦略 (例: その行が示唆する場合の onlyRenderVisibleElements) を受け入れている。

  3. 状態を配置する — ローカルフック、外部ストア、または Redux/その他を選択します。合格: 1 文でパーシスタンス、アンドゥ、またはクロスサーフェース同期がどこに存在するか、または明示的に「まだ不要」と述べている。

  4. 代替案を再チェックする — ユースケースが Consider Alternatives に該当する場合、合格: 1 文で React Flow がまだ適している理由を説明するか、代わりに選択したリストされた代替案を述べている。

アーキテクチャパターン

パッケージ構造 (xyflow)

@xyflow/system (vanilla TypeScript)
├── Core algorithms (edge paths, bounds, viewport)
├── xypanzoom (d3-based pan/zoom)
├── xydrag, xyhandle, xyminimap, xyresizer
└── Shared types

@xyflow/react (depends on @xyflow/system)
├── React components and hooks
├── Zustand store for state management
└── Framework-specific integrations

@xyflow/svelte (depends on @xyflow/system)
└── Svelte components and stores

含意: コアロジックはフレームワークに依存しません。貢献またはデバッグ時に、問題が @xyflow/system かフレームワーク固有パッケージのどちらにあるかを確認してください。

状態管理のアプローチ

1. ローカル状態 (シンプルなアプリ)

// useNodesState/useEdgesState for prototyping
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);

メリット: シンプル、ボイラープレートが少ない デメリット: 状態はコンポーネントツリーに限定される

2. 外部ストア (本番環境)

// Zustand store example
import { create } from 'zustand';

interface FlowStore {
  nodes: Node[];
  edges: Edge[];
  setNodes: (nodes: Node[]) => void;
  onNodesChange: OnNodesChange;
}

const useFlowStore = create<FlowStore>((set, get) => ({
  nodes: initialNodes,
  edges: initialEdges,
  setNodes: (nodes) => set({ nodes }),
  onNodesChange: (changes) => {
    set({ nodes: applyNodeChanges(changes, get().nodes) });
  },
}));

// In component
function Flow() {
  const { nodes, edges, onNodesChange } = useFlowStore();
  return <ReactFlow nodes={nodes} onNodesChange={onNodesChange} />;
}

メリット: 状態はどこからでもアクセス可能、パーシスタンス/同期が簡単 デメリット: セットアップが多い、セレクタ最適化に注意が必要

3. Redux/その他の状態管理ライブラリ

// Connect via selectors
const nodes = useSelector(selectNodes);
const dispatch = useDispatch();

const onNodesChange = useCallback((changes: NodeChange[]) => {
  dispatch(nodesChanged(changes));
}, [dispatch]);

データフローアーキテクチャ

User Input → Change Event → Reducer/Handler → State Update → Re-render
     ↓
[Drag node] → onNodesChange → applyNodeChanges → setNodes → ReactFlow
     ↓
[Connect]   → onConnect → addEdge → setEdges → ReactFlow
     ↓
[Delete]    → onNodesDelete → deleteElements → setNodes/setEdges → ReactFlow

サブフローパターン (ネストされたノード)

// Parent node containing child nodes
const nodes = [
  {
    id: 'group-1',
    type: 'group',
    position: { x: 0, y: 0 },
    style: { width: 300, height: 200 },
  },
  {
    id: 'child-1',
    parentId: 'group-1',  // Key: parent reference
    extent: 'parent',      // Key: constrain to parent
    position: { x: 10, y: 30 },  // Relative to parent
    data: { label: 'Child' },
  },
];

検討事項:

  • ドラッグを親に制限するには extent: 'parent' を使用
  • 親を自動展開するには expandParent: true を使用
  • 親の z-index は子のレンダリング順序に影響

ビューポートの永続化

// Save viewport state
const { toObject, setViewport } = useReactFlow();

const handleSave = () => {
  const flow = toObject();
  // flow.nodes, flow.edges, flow.viewport
  localStorage.setItem('flow', JSON.stringify(flow));
};

const handleRestore = () => {
  const flow = JSON.parse(localStorage.getItem('flow'));
  setNodes(flow.nodes);
  setEdges(flow.edges);
  setViewport(flow.viewport);
};

統合パターン

バックエンド/API との統合

// Load from API
useEffect(() => {
  fetch('/api/flow')
    .then(r => r.json())
    .then(({ nodes, edges }) => {
      setNodes(nodes);
      setEdges(edges);
    });
}, []);

// Debounced auto-save
const debouncedSave = useMemo(
  () => debounce((nodes, edges) => {
    fetch('/api/flow', {
      method: 'POST',
      body: JSON.stringify({ nodes, edges }),
    });
  }, 1000),
  []
);

useEffect(() => {
  debouncedSave(nodes, edges);
}, [nodes, edges]);

レイアウトアルゴリズムとの統合

import dagre from 'dagre';

function getLayoutedElements(nodes: Node[], edges: Edge[]) {
  const g = new dagre.graphlib.Graph();
  g.setGraph({ rankdir: 'TB' });
  g.setDefaultEdgeLabel(() => ({}));

  nodes.forEach((node) => {
    g.setNode(node.id, { width: 150, height: 50 });
  });

  edges.forEach((edge) => {
    g.setEdge(edge.source, edge.target);
  });

  dagre.layout(g);

  return {
    nodes: nodes.map((node) => {
      const pos = g.node(node.id);
      return { ...node, position: { x: pos.x, y: pos.y } };
    }),
    edges,
  };
}

パフォーマンススケーリング

ノード数ガイドライン

ノード数戦略
< 100デフォルト設定
100-500onlyRenderVisibleElements を有効化
500-1000カスタムノードを簡素化、DOM 要素を削減
> 1000仮想化、WebGL 代替案の検討

最適化テクニック

<ReactFlow
  // Only render nodes/edges in viewport
  onlyRenderVisibleElements={true}

  // Reduce node border radius (improves intersect calculations)
  nodeExtent={[[-1000, -1000], [1000, 1000]]}

  // Disable features not needed
  elementsSelectable={false}
  panOnDrag={false}
  zoomOnScroll={false}
/>

トレードオフ

制御 vs 非制御

制御非制御
ボイラープレートが多いコードが少ない
完全な状態制御内部状態
パーシスタンスが簡単toObject() が必要
複雑なアプリに最適プロトタイプに良い

接続モード

Strict (デフォルト)Loose
Source → Target のみあらゆるハンドル → あらゆるハンドル
予測可能な動作より柔軟
データフロー向けダイアグラム向け
<ReactFlow connectionMode={ConnectionMode.Loose} />

エッジレンダリング

デフォルトエッジカスタムエッジ
高速レンダリングより多くの制御
スタイリングに制限あらゆる SVG/HTML
シンプルなユースケース複雑なラベル

ライセンス: Apache-2.0(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
existential-birds
リポジトリ
existential-birds/beagle
ライセンス
Apache-2.0
最終更新
不明

Source: https://github.com/existential-birds/beagle / ライセンス: Apache-2.0

関連スキル

汎用ソフトウェア開発⭐ リポ 39,967

doubt-driven-development

重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。

by addyosmani
汎用ソフトウェア開発⭐ リポ 1,175

apprun-skills

TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。

by yysun
OpenAIソフトウェア開発⭐ リポ 797

desloppify

コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。

by Git-on-my-level
汎用ソフトウェア開発⭐ リポ 39,967

debugging-and-error-recovery

テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。

by addyosmani
汎用ソフトウェア開発⭐ リポ 39,967

test-driven-development

テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。

by addyosmani
汎用ソフトウェア開発⭐ リポ 39,967

incremental-implementation

変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。

by addyosmani
本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: existential-birds · existential-birds/beagle · ライセンス: Apache-2.0