Skip to content

Commit

Permalink
feat(hooks): add useNodesState and useEdgesState
Browse files Browse the repository at this point in the history
  • Loading branch information
moklick committed Nov 26, 2021
1 parent 713e7e1 commit a032306
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 76 deletions.
18 changes: 4 additions & 14 deletions example/src/Basic/index.tsx
Expand Up @@ -3,17 +3,15 @@ import { useState, MouseEvent, useCallback } from 'react';
import ReactFlow, {
addEdge,
Background,
applyNodeChanges,
applyEdgeChanges,
MiniMap,
Controls,
Node,
Edge,
NodeChange,
EdgeChange,
OnLoadParams,
Connection,
MarkerType,
useNodesState,
useEdgesState,
} from 'react-flow-renderer';
import DebugNode from './DebugNode';

Expand Down Expand Up @@ -108,8 +106,8 @@ const nodeTypes = {

const BasicFlow = () => {
const [rfInstance, setRfInstance] = useState<OnLoadParams | null>(null);
const [nodes, setNodes] = useState<Node[]>(initialNodes);
const [edges, setEdges] = useState<Edge[]>(initialEdges);
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);

const onConnect = useCallback((connection: Connection) => {
setEdges((eds) => {
Expand Down Expand Up @@ -152,14 +150,6 @@ const BasicFlow = () => {
});
};

const onNodesChange = useCallback((changes: NodeChange[]) => {
setNodes((ns) => applyNodeChanges(changes, ns));
}, []);

const onEdgesChange = useCallback((changes: EdgeChange[]) => {
setEdges((es) => applyEdgeChanges(changes, es));
}, []);

return (
<ReactFlow
nodes={nodes}
Expand Down
22 changes: 6 additions & 16 deletions example/src/CustomNode/index.tsx
@@ -1,4 +1,4 @@
import { useState, useEffect, MouseEvent, useCallback } from 'react';
import { useState, useEffect, MouseEvent } from 'react';
import { ChangeEvent } from 'react';

import ReactFlow, {
Expand All @@ -10,11 +10,8 @@ import ReactFlow, {
Position,
SnapGrid,
Connection,
Edge,
NodeChange,
applyNodeChanges,
applyEdgeChanges,
EdgeChange,
useNodesState,
useEdgesState,
} from 'react-flow-renderer';

import ColorSelectorNode from './ColorSelectorNode';
Expand All @@ -35,8 +32,9 @@ const nodeTypes = {
};

const CustomNodeFlow = () => {
const [nodes, setNodes] = useState<Node[]>([]);
const [edges, setEdges] = useState<Edge[]>([]);
const [nodes, setNodes, onNodesChange] = useNodesState([]);
const [edges, setEdges, onEdgesChange] = useEdgesState([]);

const [bgColor, setBgColor] = useState<string>(initBgColor);

useEffect(() => {
Expand Down Expand Up @@ -103,14 +101,6 @@ const CustomNodeFlow = () => {
const onConnect = (connection: Connection) =>
setEdges((eds) => addEdge({ ...connection, animated: true, style: { stroke: '#fff' } }, eds));

const onNodesChange = useCallback((changes: NodeChange[]) => {
setNodes((ns) => applyNodeChanges(changes, ns));
}, []);

const onEdgesChange = useCallback((changes: EdgeChange[]) => {
setEdges((es) => applyEdgeChanges(changes, es));
}, []);

return (
<ReactFlow
nodes={nodes}
Expand Down
22 changes: 5 additions & 17 deletions example/src/FloatingEdges/index.tsx
@@ -1,17 +1,13 @@
import { useState, useCallback } from 'react';
import { useCallback } from 'react';

import ReactFlow, {
addEdge,
Background,
OnLoadParams,
EdgeTypesType,
Node,
Connection,
Edge,
applyNodeChanges,
applyEdgeChanges,
NodeChange,
EdgeChange,
useNodesState,
useEdgesState,
} from 'react-flow-renderer';

import './style.css';
Expand All @@ -29,21 +25,13 @@ const edgeTypes: EdgeTypesType = {
};

const FloatingEdges = () => {
const [nodes, setNodes] = useState<Node[]>(initialNodes);
const [edges, setEdges] = useState<Edge[]>(initialEdges);
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);

const onConnect = useCallback((connection: Connection) => {
setEdges((eds) => addEdge(connection, eds));
}, []);

const onNodesChange = useCallback((changes: NodeChange[]) => {
setNodes((ns) => applyNodeChanges(changes, ns));
}, []);

const onEdgesChange = useCallback((changes: EdgeChange[]) => {
setEdges((es) => applyEdgeChanges(changes, es));
}, []);

return (
<div className="floatingedges">
<ReactFlow
Expand Down
16 changes: 13 additions & 3 deletions example/src/Hidden/index.tsx
@@ -1,7 +1,16 @@
import { useState, useCallback } from 'react';

import { useEffect } from 'react';
import ReactFlow, { addEdge, MiniMap, Controls, Connection, Edge, Node } from 'react-flow-renderer';
import ReactFlow, {
addEdge,
MiniMap,
Controls,
Connection,
Edge,
Node,
useNodesState,
useEdgesState,
} from 'react-flow-renderer';

const initialNodes: Node[] = [
{ id: '1', type: 'input', hidden: true, data: { label: 'Node 1' }, position: { x: 250, y: 5 } },
Expand All @@ -23,8 +32,9 @@ const setHidden = (hidden: boolean) => (els: any[]) =>
});

const HiddenFlow = () => {
const [nodes, setNodes] = useState<Node[]>(initialNodes);
const [edges, setEdges] = useState<Edge[]>(initialEdges);
const [nodes, setNodes] = useNodesState(initialNodes);
const [edges, setEdges] = useEdgesState(initialEdges);

const [isHidden, setIsHidden] = useState<boolean>(true);

const onConnect = useCallback((connection: Connection) => {
Expand Down
18 changes: 6 additions & 12 deletions example/src/Layouting/index.tsx
@@ -1,4 +1,4 @@
import { useState, useCallback } from 'react';
import { useCallback } from 'react';
import ReactFlow, {
ReactFlowProvider,
addEdge,
Expand All @@ -7,15 +7,15 @@ import ReactFlow, {
Controls,
NodeChange,
EdgeChange,
Node,
Connection,
Edge,
CoordinateExtent,
Position,
useNodesState,
useEdgesState,
} from 'react-flow-renderer';
import dagre from 'dagre';

import initialNodesAndEdges from './initial-elements';
import initialItems from './initial-elements';

import './layouting.css';

Expand All @@ -28,8 +28,8 @@ const nodeExtent: CoordinateExtent = [
];

const LayoutFlow = () => {
const [nodes, setNodes] = useState<Node[]>(initialNodesAndEdges.nodes);
const [edges, setEdges] = useState<Edge[]>(initialNodesAndEdges.edges);
const [nodes, setNodes, onNodesChange] = useNodesState(initialItems.nodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialItems.edges);

const onConnect = useCallback((connection: Connection) => {
setEdges((eds) => addEdge(connection, eds));
Expand Down Expand Up @@ -63,12 +63,6 @@ const LayoutFlow = () => {
setNodes(layoutedNodes);
};

const onNodesChange = useCallback((changes: NodeChange[]) => setNodes((ns) => applyNodeChanges(changes, ns)), []);

const onEdgesChange = useCallback((changes: EdgeChange[]) => {
setEdges((es) => applyEdgeChanges(changes, es));
}, []);

return (
<div className="layoutflow">
<ReactFlowProvider>
Expand Down
18 changes: 4 additions & 14 deletions example/src/NestedNodes/index.tsx
Expand Up @@ -3,14 +3,12 @@ import { useState, MouseEvent, useCallback } from 'react';
import ReactFlow, {
addEdge,
Background,
applyNodeChanges,
applyEdgeChanges,
useNodesState,
useEdgesState,
MiniMap,
Controls,
Node,
Edge,
NodeChange,
EdgeChange,
OnLoadParams,
Connection,
} from 'react-flow-renderer';
Expand Down Expand Up @@ -87,8 +85,8 @@ const initialEdges: Edge[] = [

const NestedFlow = () => {
const [rfInstance, setRfInstance] = useState<OnLoadParams | null>(null);
const [nodes, setNodes] = useState<Node[]>(initialNodes);
const [edges, setEdges] = useState<Edge[]>(initialEdges);
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);

const onConnect = useCallback((connection: Connection) => {
setEdges((eds) => addEdge(connection, eds));
Expand Down Expand Up @@ -129,14 +127,6 @@ const NestedFlow = () => {
});
};

const onNodesChange = useCallback((changes: NodeChange[]) => {
setNodes((ns) => applyNodeChanges(changes, ns));
}, []);

const onEdgesChange = useCallback((changes: EdgeChange[]) => {
setEdges((es) => applyEdgeChanges(changes, es));
}, []);

return (
<ReactFlow
nodes={nodes}
Expand Down
27 changes: 27 additions & 0 deletions src/hooks/useNodesEdgesState.ts
@@ -0,0 +1,27 @@
import { useState, useCallback, SetStateAction, Dispatch } from 'react';

import { applyNodeChanges, applyEdgeChanges } from '../utils/changes';
import { Node, NodeChange, Edge, EdgeChange } from '../types';

type ApplyChanges<ItemType, ChangesType> = (changes: ChangesType[], items: ItemType[]) => ItemType[];
type OnChange<ChangesType> = (changes: ChangesType[]) => void;

// returns a hook that can be used liked this:
// const [nodes, setNodes, onNodesChange] = useNodesState(intialNodes);
function createUseItemsState<ItemType, ChangesType>(
applyChangesFunction: ApplyChanges<ItemType, ChangesType>
): (initialItems: ItemType[]) => [ItemType[], Dispatch<SetStateAction<ItemType[]>>, OnChange<ChangesType>] {
return (initialItems: ItemType[]) => {
const [items, setItems] = useState<ItemType[]>(initialItems);

const onItemsChange = useCallback(
(changes: ChangesType[]) => setItems((items) => applyChangesFunction(changes, items)),
[]
);

return [items, setItems, onItemsChange];
};
}

export const useNodesState = createUseItemsState<Node, NodeChange>(applyNodeChanges as ApplyChanges<Node, NodeChange>);
export const useEdgesState = createUseItemsState<Edge, EdgeChange>(applyEdgeChanges as ApplyChanges<Edge, EdgeChange>);
1 change: 1 addition & 0 deletions src/index.ts
Expand Up @@ -27,6 +27,7 @@ export { applyNodeChanges, applyEdgeChanges } from './utils/changes';

export { default as useZoomPanHelper } from './hooks/useZoomPanHelper';
export { default as useUpdateNodeInternals } from './hooks/useUpdateNodeInternals';
export * from './hooks/useNodesEdgesState';

export * from './additional-components';
export { useStore, useStoreApi } from './store';
Expand Down

0 comments on commit a032306

Please sign in to comment.