學習自訂 React Flow

自訂節點

React Flow 的一個強大功能是能夠新增自訂節點。在自訂節點中,您可以渲染任何您想要的東西。您可以定義多個來源和目標控制點,並渲染表單輸入或圖表等。在本節中,我們將實作一個具有輸入欄位的節點,該欄位會更新應用程式另一部分中的一些文字。

實作自訂節點

自訂節點是一個 React 元件,它被包裝起來以提供基本功能,例如選取或拖曳。從包裝元件中,我們傳遞屬性,例如位置或資料,以及其他屬性。讓我們開始實作 TextUpdaterNode。我們使用 Handle 元件,以便能夠將我們的自訂節點與其他節點連接,並將輸入欄位新增至節點

import { useCallback } from 'react';
import { Handle, Position } from '@xyflow/react';
 
const handleStyle = { left: 10 };
 
function TextUpdaterNode({ data }) {
  const onChange = useCallback((evt) => {
    console.log(evt.target.value);
  }, []);
 
  return (
    <>
      <Handle type="target" position={Position.Top} />
      <div>
        <label htmlFor="text">Text:</label>
        <input id="text" name="text" onChange={onChange} className="nodrag" />
      </div>
      <Handle type="source" position={Position.Bottom} id="a" />
      <Handle
        type="source"
        position={Position.Bottom}
        id="b"
        style={handleStyle}
      />
    </>
  );
}

如您所見,我們已將類別名稱「nodrag」新增至輸入。這可以防止在輸入欄位中拖曳,並讓我們選取文字等。

新增節點類型

您可以將新的節點類型新增至 React Flow,方法是將其新增至 nodeTypes 屬性。重要的是,nodeTypes 會進行記憶或在元件外部定義。否則,React 會在每次渲染時建立一個新物件,這會導致效能問題和錯誤。

const nodeTypes = useMemo(() => ({ textUpdater: TextUpdaterNode }), []);
 
return <ReactFlow nodeTypes={nodeTypes} />;

在定義新的節點類型之後,您可以使用 type 節點選項來使用它

const nodes = [
  {
    id: 'node-1',
    type: 'textUpdater',
    position: { x: 0, y: 0 },
    data: { value: 123 },
  },
];

將所有內容放在一起並新增一些基本樣式後,我們將獲得一個將文字列印到主控台的自訂節點

export default function App() {
  const data: string = "world"

  return <h1>Hello {data}</h1>
}

唯讀

使用多個控制點

如您所見,我們在節點中新增了兩個來源控制點,使其具有兩個輸出。如果您想要將其他節點與這些特定控制點連接,則節點 ID 不夠,您還需要傳遞特定控制點 ID。在此情況下,一個控制點的 ID 為 "a",另一個控制點的 ID 為 "b"。控制點特定的邊緣使用 sourceHandletargetHandle 選項,這些選項會參照節點中的控制點

const initialEdges = [
  { id: 'edge-1', source: 'node-1', sourceHandle: 'a', target: 'node-2' },
  { id: 'edge-2', source: 'node-1', sourceHandle: 'b', target: 'node-3' },
];

在此情況下,來源節點是兩個控制點的 node-1,但控制點 ID 不同。一個來自控制點 ID "a",另一個來自 "b"。兩個邊緣也具有不同的目標節點

export default function App() {
  const data: string = "world"

  return <h1>Hello {data}</h1>
}

唯讀

請注意,如果您是以程式方式變更自訂節點中控制點的位置或數量,則需要使用 useUpdateNodeInternals hook,以正確通知 ReactFlow 變更。從這裡,您應該能夠建置您的自訂節點。在大多數情況下,我們建議僅使用自訂節點。內建的節點僅為基本範例。您可以在自訂節點 API 區段中找到已傳遞屬性的清單和更多資訊。