React Flow 12への移行
サーバーサイドレンダリング、フローの計算、ダークモードなど、React Flow 12に搭載されている新機能を使用する前に、まず対処すべき破壊的変更点があります。破壊的変更を最小限に抑えるように努めましたが、新機能を実装するために必要な変更もありました。
移行ガイド
移行を開始する前に、新しいパッケージをインストールする必要があります。
npm install @xyflow/react
1. 新しいnpmパッケージ名
パッケージ reactflow
は @xyflow/react
に名前が変更され、デフォルトのインポートではなくなりました。スタイルのインポートも調整する必要があります。v12より前は、React Flowは複数のパッケージに分割されていました。 अब ऐसा नहीं है। コアのみを使用していた場合は、@xyflow/react
パッケージをインストールする必要があります。
古いAPI
// npm install reactflow
import ReactFlow from 'reactflow';
新しいAPI
// npm install @xyflow/react
import { ReactFlow } from '@xyflow/react';
// you also need to adjust the style import
import '@xyflow/react/dist/style.css';
// or if you just want basic styles
import '@xyflow/react/dist/base.css';
2. ノードの測定された width
と height
を示す measured
属性
測定されたすべてのノード値は、node.measured
に格納されるようになりました。新しいパッケージ名に加えて、これは最大の変更点です。React Flowはノードを測定した後、寸法を node.measured.width
と node.measured.height
に書き込みます。dagreやelkなどのレイアウトライブラリを使用している場合は、node
の代わりに node.measured
から寸法を取得する必要があります。width
と height
を使用している場合、これらの値はインラインスタイルとして使用され、ノードの寸法を指定します。
古いAPI
// getting the measured width and height
const nodeWidth = node.width;
const nodeHeight = node.height;
新しいAPI
// getting the measured width and height
const nodeWidth = node.measured?.width;
const nodeHeight = node.measured?.height;
3. 新しい寸法処理 node.width
/ node.height
vs node.measured.width
/ node.measured.height
サーバーサイドレンダリングをサポートするために、APIを少し再構築して、ユーザーがノードの寸法をより簡単に渡せるようにする必要がありました。このため、node.width
属性と node.height
属性の動作を変更しました。React Flow 11では、これらの属性は測定値であり、参照としてのみ使用されていました。React Flow 12では、これらの属性はインラインスタイルとして使用され、ノードの寸法を指定します。データベースからノードを読み込む場合は、動作が少し変更されたため、ノードから width
属性と height
属性を削除することをお勧めします。width
と height
を使用すると、寸法はコンテンツに基づいて動的に変化するのではなく、固定されることを意味します。
古いAPI
// in React Flow 11 you might used node.style to set the dimensions
const nodes = [
{
id: '1',
type: 'input',
data: { label: 'input node' },
position: { x: 250, y: 5 },
style: { width: 180, height: 40 },
},
];
新しいAPI
// in React Flow 12 you can used node.width and node.height to set the dimensions
const nodes = [
{
id: '1',
type: 'input',
data: { label: 'input node' },
position: { x: 250, y: 5 },
width: 180,
height: 40,
},
];
React Flowをサーバーサイドレンダリング用に構成する方法の詳細については、サーバーサイドレンダリングガイドをご覧ください。
4. ノードとエッジの更新
オブジェクトの変更によるノードとエッジの更新はサポートされなくなりました。特定の属性を更新する場合は、新しいノード/エッジを作成する必要があります。
古いAPI
setNodes((currentNodes) =>
currentNodes.map((node) => {
node.hidden = true;
return node;
}),
);
新しいAPI
setNodes((currentNodes) =>
currentNodes.map((node) => ({
...node,
hidden: true,
})),
);
5. onEdgeUpdate
(および関連API)の名前を onReconnect
に変更
onEdgeUpdate
関数の名前を onReconnect
に変更し、関連するすべてのAPI(下記参照)の名前を変更しました。新しい名前はより記述的で、関数がエッジの再接続に使用されることを明確にしています。
updateEdge
はreconnectEdge
に名前変更されましたonEdgeUpdateStart
はonReconnectStart
に名前変更されましたonEdgeUpdate
はonReconnect
に名前変更されましたonEdgeUpdateEnd
はonReconnectEnd
に名前変更されましたedgeUpdaterRadius
はreconnectRadius
に名前変更されましたedge.updatable
はedge.reconnectable
に名前変更されましたedgesUpdatable
はedgesReconnectable
に名前変更されました
古いAPI
<ReactFlow
onEdgeUpdate={onEdgeUpdate}
onEdgeUpdateStart={onEdgeUpdateStart}
onEdgeUpdateEnd={onEdgeUpdateEnd}
/>
新しいAPI
<ReactFlow
onReconnect={onReconnect}
onReconnectStart={onReconnectStart}
onReconnectEnd={onReconnectEnd}
/>
6. parentNode
の名前を parentId
に変更
サブフローを使用している場合は、node.parentNode
を node.parentId
に名前変更する必要があります。parentNode
属性は、親ノードへの参照ではなく、親ノードの id
であったため、少し誤解を招く恐れがありました。
古いAPI
const nodes = [
// some nodes ...
{
id: 'xyz-id',
position: { x: 0, y: 0 },
type: 'default',
data: {},
parentNode: 'abc-id',
},
];
新しいAPI
const nodes = [
// some nodes ...
{
id: 'xyz-id',
position: { x: 0, y: 0 },
type: 'default',
data: {},
parentId: 'abc-id',
},
];
7. カスタムノードのプロパティ
xPos
プロパティと yPos
プロパティの名前を positionAbsoluteX
と positionAbsoluteY
に変更しました
古いAPI
function CustomNode({ xPos, yPos }) {
...
}
新しいAPI
function CustomNode({ positionAbsoluteX, positionAbsoluteY }) {
...
}
8. コンポーネントクラス名の処理
ハンドルの現在の状態を定義するために使用されるクラスの一部を名前変更しました。
react-flow__handle-connecting
はconnectingto
/connectingfrom
に名前変更されましたreact-flow__handle-valid
はvalid
に名前変更されました
9. getNodesBounds
オプション
2番目のパラメータのタイプが nodeOrigin
から options.nodeOrigin
に変更されました
古いAPI
const bounds = getNodesBounds(nodes: Node[], nodeOrigin)
新しいAPI
const bounds = getNodesBounds(nodes: Node[], { nodeOrigin })
10. ノードとエッジを定義するためのTypescriptの変更
型を簡素化し、ユーザーがNodeDataジェネリックを渡すことができた関数に関する問題を修正しました。新しい方法は、すべてのノードの和集合を使用して独自のノード型を定義することです。この変更により、異なるデータ構造を持つ複数のノード型を持つことができ、node.type
属性をチェックすることで常に区別できるようになりました。
新しいAPI
type NumberNode = Node<{ value: number }, 'number'>;
type TextNode = Node<{ text: string }, 'text'>;
type AppNode = NumberNode | TextNode;
その後、AppNode
タイプを次のように使用できます
const nodes: AppNode[] = [
{ id: '1', type: 'number', data: { value: 1 }, position: { x: 100, y: 100 } },
{ id: '2', type: 'text', data: { text: 'Hello' }, position: { x: 200, y: 200 } },
];
const onNodesChange: onNodesChange<AppNode> = useCallback((changes) => setNodes(nds => applyChanges(changes, nds)), []);
詳細については、Typescriptガイドをご覧ください。
11. nodeInternals
の名前変更
nodeInternals
を使用している場合は、nodeLookup
に名前を変更する必要があります。
古いAPI
const node = useStore((s) => s.nodeInternals.get(id));
新しいAPI
const node = useStore((s) => s.nodeLookup.get(id));
12. 非推奨関数の削除
以下の非推奨関数を削除しました。
getTransformForBounds
(getViewportForBounds
に置き換えられました)getRectOfNodes
(getNodesBounds
に置き換えられました)project
(screenToFlowPosition
に置き換えられました)getMarkerEndId
updateEdge
(reconnectEdge
に置き換えられました)
13. カスタム applyNodeChanges
と applyEdgeChanges
変更を適用するための独自の関数を作成した場合、新しい「replace」イベントを処理する必要があります。「reset」イベントは削除され、特定のノードまたはエッジを置き換える「replace」イベントが追加されました。
新機能
v12 に正常に移行したので、すべての素晴らしい機能を使用できます。上記のように、v12 の最大の更新点は次のとおりです。
1. サーバーサイドレンダリング
ノードの width
、height
、handles
を定義できます。これにより、サーバー上でフローをレンダリングし、クライアント上でハイドレートすることができます:サーバーサイドレンダリングガイド。
- **詳細:** v11 では、ノードが測定されるとすぐにライブラリによって
width
とheight
が設定されていました。これは引き続き行われますが、この情報を格納するためにmeasured.width
とmeasured.height
を使用するようになりました。以前のバージョンでは、width
とheight
について常に多くの混乱がありました。実際の幅や高さを渡すために使用できないことを理解するのは困難です。また、これらの属性がライブラリによって追加されることは明らかではありません。新しい実装は両方の問題を解決すると考えています。width
とheight
は、寸法を定義するために使用できるオプションの属性であり、ライブラリによって設定されるすべてのものはmeasured
に格納されます。
2. フローの計算
新しいフック useHandleConnections
と useNodesData
、および新しい updateNode
と updateNodeData
関数(どちらも useReactFlow
の一部)を使用して、ノード間のデータフローを管理できます:フローの計算ガイド。エッジ用のヘルパー(updateEdge
と updateEdgeData
)も追加しました!
- **詳細:** あるノードのデータが別のノードに依存するフローを扱うことは非常に一般的です。ノードAを更新し、接続されたノードBでこれらの変更に反応したいとします。これまで、誰もがカスタムソリューションを考え出す必要がありました。このバージョンでは、これを変更し、このようなユースケースを処理するための高性能なヘルパーを提供します。
3. ダークモードとCSS変数
React Flow には、新しい colorMode
プロパティ(「light」、「dark」、または「system」)を使用して切り替えることができる、組み込みのダークモードが付属するようになりました:ダークモードの例
- **詳細:** このバージョンでは、ダークモードとライトモードの切り替えを容易にし、ダークフローのより良い出発点を提供します。
colorMode="dark"
を渡すと、ラッパークラス名「dark」が追加され、スタイリングの調整に使用されます。この新機能の実装を容易にするために、ほとんどのスタイルで CSS 変数に切り替えました。これらの変数は、ユーザーランドでもフローをカスタマイズするために使用できます。
4. TSDoc によるより良い DX
より良い DX のために TSDoc を使用し始めました。開発中に、IDE にプロパティとフックのドキュメントが表示されるようになりました。これは、ライブラリをよりアクセスしやすく、使いやすくするための大きな一歩です。近い将来、TSDoc を使用してドキュメントを生成する予定です。
その他の機能と更新
他にもあります!新しい主な機能に加えて、長い間リストに載っていたマイナーな事項をいくつか追加しました。
- **
useConnection
フック:** このフックを使用すると、進行中の接続にアクセスできます。たとえば、現在の開始/終了ハンドルに基づいて、ハンドルを色付けしたり、カスタム接続線をスタイルしたりするために使用できます。 - **制御された
viewport
:** これは高度な機能です。考えられるユースケースは、ビューポートをアニメーション化したり、たとえば低解像度画面の変換を丸めたりすることです。この機能は、2つの新しいプロパティをもたらします:viewport
とonViewportChange
。 - **
ViewportPortal
コンポーネント:** これにより、カスタムノードを実装する必要なく、ビューポートに要素をレンダリングできます。 - **
onDelete
ハンドラ**:削除に反応しやすくするために、onDeleteNodes
とonDeleteEdges
のための結合ハンドラを追加しました。 - **
onBeforeDelete
ハンドラ**:このハンドラを使用すると、削除を防止/管理できます。 - **
isValidConnection
プロパティ:** すべての接続に1つの検証関数を実装することができます。プログラムで追加されたエッジにも呼び出されます。 - **
autoPanSpeed
プロパティ:** 自動パン中の速度を制御します。 - **
paneClickDistance
プロパティ:** クリックをトリガーするmousedown/up間の最大距離。 - **背景コンポーネント**:クラス名を使用して背景パターンをスタイルできるように、
patternClassName
プロパティを追加します。これは、たとえばTailwindで背景パターンをスタイルする場合に便利です。 - **
onMove
コールバック**は、ライブラリによって呼び出されたビューポートの更新(fitViewやズームインなど)に対してトリガーされます - **
deleteElements
** は、削除されたノードと削除されたエッジを返すようになりました - ノードに **
origin
属性**を追加 - エッジに **
selectable
属性**を追加 - **ノードリサイザーの更新**:グループのサイズ変更時に子ノードが移動せず、エクステントと展開が正しく認識される
BezierEdge
、StepEdge
、SmoothStepEdge
、StraightEdge
コンポーネントの正しい型- ライブラリによって新しく作成されたエッジは、これらの属性が設定されている場合にのみ、
sourceHandle
とtargetHandle
属性を持ちます。(以前はsourceHandle: null
とtargetHandle: null
を渡していました) - z-indexが変更されてもエッジはマウント/アンマウントされない
- 接続線はターゲットハンドルの位置を認識しているため、パスが正しく描画される
nodeDragThreshold
は0ではなくデフォルトで1- 選択ボックスの使い勝手の向上(フローからドラッグアウト中のキャプチャ)
NodeProps
にselectable
、deletable
、draggable
、parentId
を追加- スタイルがロードされていない場合の警告を追加
内部変更
これらの変更は実際にはユーザー向けではありませんが、内部のReact Flowストアで作業している人にとっては重要かもしれません
- 最大の内部変更は、React FlowとSvelte Flowで使用できる **フレームワークに依存しないヘルパーを備えた新しいパッケージ@xyflow/system** を作成したことです。
- ノードと選択のドラッグを処理するための **XYDrag**
- ビューポートのパンとズームを制御するための **XYPanZoom**
- 新しい接続を管理するための **XYHandle**
nodeInternals
をnodeLookup
に名前変更しました。このマップはルックアップとして機能しますが、変更のたびに新しいマップオブジェクトを作成することはないため、実際にはルックアップとしてのみ役立ちます。- 内部「reset」イベントを削除し、特定のノードを更新できるように「replace」イベントを追加しました。
- ストアから
connectionNodeId
、connectionHandleId
、connectionHandleType
を削除し、connection.fromHandle.nodeId
、connection.fromHandle.id
、… を追加しました - エッジに
data-id
を追加する - ユーザーが選択範囲をドラッグしたときにも、
onNodeDragStart
、onNodeDrag
、onNodeDragStop
が呼び出されます(onSelectionDragStart
、onSelectionDrag
、onSelectionDragStop
に加えて)。