feat(hooks): add useNodesData, useUpdateNodeData, simplify useHandleConnections
This commit is contained in:
@@ -44,8 +44,9 @@ import CancelConnection from '../examples/CancelConnection';
|
||||
import InteractiveMinimap from '../examples/InteractiveMinimap';
|
||||
import UseOnSelectionChange from '../examples/UseOnSelectionChange';
|
||||
import NodeToolbar from '../examples/NodeToolbar';
|
||||
import useNodesInitialized from '../examples/UseNodesInit';
|
||||
import useHandleConnectionStatus from '../examples/UseHandleConnectionStatus';
|
||||
import UseNodesInitialized from '../examples/UseNodesInit';
|
||||
import UseNodesData from '../examples/UseNodesData';
|
||||
import UseHandleConnections from '../examples/UseHandleConnections';
|
||||
|
||||
export interface IRoute {
|
||||
name: string;
|
||||
@@ -262,7 +263,7 @@ const routes: IRoute[] = [
|
||||
{
|
||||
name: 'useNodesInitialized',
|
||||
path: 'use-nodes-initialized',
|
||||
component: useNodesInitialized,
|
||||
component: UseNodesInitialized,
|
||||
},
|
||||
{
|
||||
name: 'useOnSelectionChange',
|
||||
@@ -275,9 +276,14 @@ const routes: IRoute[] = [
|
||||
component: UseReactFlow,
|
||||
},
|
||||
{
|
||||
name: 'useHandleConnectionStatus',
|
||||
path: 'usehandleconnectionstatus',
|
||||
component: useHandleConnectionStatus,
|
||||
name: 'useHandleConnections',
|
||||
path: 'usehandleconnections',
|
||||
component: UseHandleConnections,
|
||||
},
|
||||
{
|
||||
name: 'useNodesData',
|
||||
path: 'usenodesdata',
|
||||
component: UseNodesData,
|
||||
},
|
||||
{
|
||||
name: 'useUpdateNodeInternals',
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { memo, FC, useEffect, useCallback } from 'react';
|
||||
import { Handle, Position, NodeProps, useHandleConnectionStatus, Connection } from '@xyflow/react';
|
||||
import { HandleComponentProps } from '@xyflow/react/dist/esm/components/Handle';
|
||||
import { Handle, Position, NodeProps, useHandleConnections, Connection, HandleComponentProps } from '@xyflow/react';
|
||||
|
||||
function CustomHandle({ nodeId, ...handleProps }: HandleComponentProps & { nodeId: string }) {
|
||||
const onConnect = useCallback(
|
||||
@@ -12,7 +11,7 @@ function CustomHandle({ nodeId, ...handleProps }: HandleComponentProps & { nodeI
|
||||
(connections: Connection[]) => console.log('onDisconnect handler, node id:', nodeId, connections),
|
||||
[nodeId]
|
||||
);
|
||||
const status = useHandleConnectionStatus({
|
||||
const connections = useHandleConnections({
|
||||
handleType: handleProps.type,
|
||||
handleId: handleProps.id,
|
||||
onConnect,
|
||||
@@ -20,8 +19,8 @@ function CustomHandle({ nodeId, ...handleProps }: HandleComponentProps & { nodeI
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
console.log('useEffect, node id:', nodeId, handleProps.type, status);
|
||||
}, [status]);
|
||||
console.log('useEffect, node id:', nodeId, handleProps.type, connections);
|
||||
}, [connections]);
|
||||
|
||||
return <Handle {...handleProps} />;
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import { memo, FC, useEffect, useCallback } from 'react';
|
||||
import { Handle, Position, NodeProps, useHandleConnectionStatus, Connection } from '@xyflow/react';
|
||||
import { HandleComponentProps } from '@xyflow/react/dist/esm/components/Handle';
|
||||
import { Handle, Position, NodeProps, useHandleConnections, Connection, HandleComponentProps } from '@xyflow/react';
|
||||
|
||||
function CustomHandle({ nodeId, ...handleProps }: HandleComponentProps & { nodeId: string }) {
|
||||
const onConnect = useCallback(
|
||||
@@ -15,7 +14,7 @@ function CustomHandle({ nodeId, ...handleProps }: HandleComponentProps & { nodeI
|
||||
},
|
||||
[nodeId]
|
||||
);
|
||||
const status = useHandleConnectionStatus({
|
||||
const connections = useHandleConnections({
|
||||
handleType: handleProps.type,
|
||||
handleId: handleProps.id,
|
||||
onConnect,
|
||||
@@ -23,8 +22,8 @@ function CustomHandle({ nodeId, ...handleProps }: HandleComponentProps & { nodeI
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
console.log('useEffect, node id:', nodeId, handleProps.type, status);
|
||||
}, [status]);
|
||||
console.log('useEffect, node id:', nodeId, handleProps.type, connections);
|
||||
}, [connections]);
|
||||
|
||||
return <Handle {...handleProps} />;
|
||||
}
|
||||
25
examples/react/src/examples/UseNodesData/ResultNode.tsx
Normal file
25
examples/react/src/examples/UseNodesData/ResultNode.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import { memo, useEffect } from 'react';
|
||||
import { Handle, Position, useHandleConnections, useNodesData } from '@xyflow/react';
|
||||
|
||||
function ResultNode() {
|
||||
const connections = useHandleConnections({
|
||||
handleType: 'target',
|
||||
});
|
||||
const nodesData = useNodesData<{ text: string }>(connections.map((connection) => connection.source));
|
||||
|
||||
useEffect(() => {
|
||||
console.log('incoming data changed', nodesData);
|
||||
}, [nodesData]);
|
||||
|
||||
return (
|
||||
<div style={{ background: '#eee', color: '#222', padding: 10, fontSize: 12, borderRadius: 10 }}>
|
||||
<Handle type="target" position={Position.Left} />
|
||||
<div>
|
||||
incoming texts:{' '}
|
||||
{nodesData?.filter((nodeData) => nodeData.text).map(({ text }, i) => <div key={i}>{text}</div>) || 'none'}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(ResultNode);
|
||||
20
examples/react/src/examples/UseNodesData/TextNode.tsx
Normal file
20
examples/react/src/examples/UseNodesData/TextNode.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import { memo, ChangeEventHandler } from 'react';
|
||||
import { Position, NodeProps, useUpdateNodeData, Handle } from '@xyflow/react';
|
||||
|
||||
function TextNode({ id, data }: NodeProps) {
|
||||
const updateNodeData = useUpdateNodeData();
|
||||
|
||||
const onChange: ChangeEventHandler<HTMLInputElement> = (evt) => updateNodeData(id, { text: evt.target.value });
|
||||
|
||||
return (
|
||||
<div style={{ background: '#eee', color: '#222', padding: 10, fontSize: 12, borderRadius: 10 }}>
|
||||
<div>node {id}</div>
|
||||
<div>
|
||||
<input onChange={onChange} value={data.text} />
|
||||
</div>
|
||||
<Handle type="source" position={Position.Right} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(TextNode);
|
||||
83
examples/react/src/examples/UseNodesData/index.tsx
Normal file
83
examples/react/src/examples/UseNodesData/index.tsx
Normal file
@@ -0,0 +1,83 @@
|
||||
import { useCallback } from 'react';
|
||||
import {
|
||||
ReactFlow,
|
||||
Controls,
|
||||
addEdge,
|
||||
Connection,
|
||||
useNodesState,
|
||||
useEdgesState,
|
||||
Background,
|
||||
Node,
|
||||
Edge,
|
||||
} from '@xyflow/react';
|
||||
|
||||
import TextNode from './TextNode';
|
||||
import ResultNode from './ResultNode';
|
||||
|
||||
const nodeTypes = {
|
||||
text: TextNode,
|
||||
result: ResultNode,
|
||||
};
|
||||
|
||||
const initNodes: Node[] = [
|
||||
{
|
||||
id: '1',
|
||||
type: 'text',
|
||||
data: {
|
||||
text: 'hello',
|
||||
},
|
||||
position: { x: 0, y: 0 },
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
type: 'text',
|
||||
data: {
|
||||
text: 'world',
|
||||
},
|
||||
position: { x: 0, y: 100 },
|
||||
},
|
||||
|
||||
{
|
||||
id: '3',
|
||||
type: 'result',
|
||||
data: {},
|
||||
position: { x: 300, y: 50 },
|
||||
},
|
||||
];
|
||||
|
||||
const initEdges: Edge[] = [
|
||||
{
|
||||
id: 'e1-3',
|
||||
source: '1',
|
||||
target: '3',
|
||||
},
|
||||
{
|
||||
id: 'e2-3',
|
||||
source: '2',
|
||||
target: '3',
|
||||
},
|
||||
];
|
||||
|
||||
const CustomNodeFlow = () => {
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState(initNodes);
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState(initEdges);
|
||||
|
||||
const onConnect = useCallback((connection: Connection) => setEdges((eds) => addEdge(connection, eds)), [setEdges]);
|
||||
|
||||
return (
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
onConnect={onConnect}
|
||||
nodeTypes={nodeTypes}
|
||||
fitView
|
||||
>
|
||||
<Controls />
|
||||
<Background />
|
||||
</ReactFlow>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomNodeFlow;
|
||||
Reference in New Issue
Block a user