句柄
¥Handles
句柄是 React Flow 中 nodes 上的连接点。我们的内置节点包含一个源句柄和一个目标句柄,但你可以根据需要使用任意数量的不同句柄自定义节点。
¥Handles are the connection points on nodes in React Flow. Our built-in nodes include one source and one target handle, but you can customize your nodes with as many different handles as you need.
创建带句柄的节点
¥Creating a Node with Handles
要创建带有句柄的 自定义节点,你可以使用 React Flow 提供的 <Handle />
组件。此组件允许你为自定义节点定义源和目标句柄。以下是如何实现带有两个句柄的自定义节点的示例:
¥To create a custom node with handles, you can use the <Handle />
component provided by React Flow. This component allows you to define source and target handles for your custom nodes. Here’s an example of how to implement a custom node with two handles:
import { Handle } from '@xyflow/react';
export function CustomNode() {
return (
<div className="custom-node">
<div>Custom Node Content</div>
<Handle type="source" position="top" />
<Handle type="target" position="bottom" />
</div>
);
}
使用多个句柄
¥Using Multiple Handles
如果你想在自定义节点中使用多个源或目标句柄,则需要为每个句柄指定一个唯一的 id
。这使得 React Flow 在连接边时能够区分不同的句柄。
¥If you want to use multiple source or target handles in your custom node, you need to specify each handle with a unique id
. This allows React Flow to differentiate between the handles when connecting edges.
<Handle type="target" position="top" />
<Handle type="source" position="right" id="a" />
<Handle type="source" position="bottom" id="b" />
要将边连接到节点的特定句柄,请使用属性 sourceHandle
(表示边的起点)和 targetHandle
(表示边的终点)。通过使用适当的句柄 id
定义 sourceHandle
或 targetHandle
,你可以指示 React Flow 将边附加到该特定句柄,确保在你想要的位置建立连接。
¥To connect an edge to a specific handle of a node, use the properties sourceHandle
(for the edge’s starting point) and targetHandle
(for the edge’s ending point). By defining sourceHandle
or targetHandle
with the appropriate handle id
, you instruct React Flow to attach the edge to that specific handle, ensuring that connections are made where you intend.
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
。两个边也有不同的目标节点:
¥In this case, the source node is node-1
for both handles but the handle id
s are different. One comes from handle id a
and the other one from b
. Both edges also have different target nodes:
import { useCallback, useState } from 'react';
import {
ReactFlow,
addEdge,
applyEdgeChanges,
applyNodeChanges,
} from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import TextUpdaterNode from './TextUpdaterNode';
const rfStyle = {
backgroundColor: '#B8CEFF',
};
const initialNodes = [
{
id: 'node-1',
type: 'textUpdater',
position: { x: 100, y: 0 },
data: { value: 123 },
},
{
id: 'node-2',
type: 'output',
targetPosition: 'top',
position: { x: 0, y: 200 },
data: { label: 'node 2' },
},
{
id: 'node-3',
type: 'output',
targetPosition: 'top',
position: { x: 200, y: 200 },
data: { label: 'node 3' },
},
];
const initialEdges = [
{ id: 'edge-1', source: 'node-1', target: 'node-2', sourceHandle: 'a' },
{ id: 'edge-2', source: 'node-1', target: 'node-3', sourceHandle: 'b' },
];
// we define the nodeTypes outside of the component to prevent re-renderings
// you could also use useMemo inside the component
const nodeTypes = { textUpdater: TextUpdaterNode };
function Flow() {
const [nodes, setNodes] = useState(initialNodes);
const [edges, setEdges] = useState(initialEdges);
return (
<ReactFlow
nodes={nodes}
edges={edges}
nodeTypes={nodeTypes}
fitView
style={rfStyle}
/>
);
}
export default Flow;
如果你以编程方式更改自定义节点中句柄的位置或数量,则需要使用 useUpdateNodeInternals
钩子正确地通知 React Flow 更改。
¥If you are programmatically changing the position or number of handles
in your custom node, you will need to use the
useUpdateNodeInternals
hook
to properly notify React Flow of changes.
自定义句柄
¥Custom handles
你可以通过封装 <Handle />
组件来创建自己的自定义句柄。此示例显示了一个自定义句柄,该句柄仅在连接源与给定的 ID 匹配时才允许连接。
¥You can create your own custom handles by wrapping the <Handle />
component.
This example shows a custom handle that only allows connections when the
connection source matches a given id.
import { Handle, Position } from '@xyflow/react';
export const TargetHandleWithValidation = ({ position, source }) => (
<Handle
type="target"
position={position}
isValidConnection={(connection) => connection.source === source}
onConnect={(params) => console.log('handle onConnect', params)}
style={{ background: '#fff' }}
/>
);
动态句柄
¥Dynamic handles
如果你以编程方式更改自定义节点中句柄的位置或数量,则需要使用 useUpdateNodeInternals
钩子更新节点内部。
¥If you are programmatically changing the position or number of handles in your
custom node, you need to update the node internals with the
useUpdateNodeInternals
hook.
你可以在 自定义节点指南 或 自定义节点示例 中找到如何使用多个句柄实现自定义节点的示例。
¥You can find an example of how to implement a custom node with multiple handles in the custom node guide or in the custom node example.
自定义句柄样式
¥Custom handle styles
由于句柄是一个 div,因此你可以使用 CSS 来设置它的样式或传递样式属性来自定义句柄。你可以在 在边缘拖放时添加节点 和 简单浮动边缘 示例中看到这一点。
¥Since the handle is a div, you can use CSS to style it or pass a style prop to customize a Handle. You can see this in the Add Node On Edge Drop and Simple Floating Edges examples.
连接时句柄的样式
¥Styling handles when connecting
当连接线位于句柄上方时,句柄会接收附加类名 connecting
,如果连接有效,则接收 valid
。你可以找到使用这些类 此处 的示例。
¥The handle receives the additional class names connecting
when the connection
line is above the handle and valid
if the connection is valid. You can find an
example which uses these classes here.
隐藏句柄
¥Hiding Handles
-
如果你出于某种原因需要隐藏句柄,则必须使用
visibility: hidden
或opacity: 0
而不是display: none
。这一点很重要,因为 React Flow 需要计算句柄的尺寸才能正常工作,而使用display: none
将报告0
的宽度和高度!¥If you need to hide a handle for some reason, you must use
visibility: hidden
oropacity: 0
instead ofdisplay: none
. This is important because React Flow needs to calculate the dimensions of the handle to work properly and usingdisplay: none
will report a width and height of0
!