import { useState, useCallback, SetStateAction, Dispatch } from 'react'; import { applyNodeChanges, applyEdgeChanges } from '../utils/changes'; import { Node, NodeChange, Edge, EdgeChange } from '../types'; type ApplyChanges = (changes: ChangesType[], items: ItemType[]) => ItemType[]; type OnChange = (changes: ChangesType[]) => void; // returns a hook that can be used liked this: // const [nodes, setNodes, onNodesChange] = useNodesState(intialNodes); function createUseItemsState( applyChangesFunction: ApplyChanges ): (initialItems: ItemType[]) => [ItemType[], Dispatch>, OnChange] { return (initialItems: ItemType[]) => { const [items, setItems] = useState(initialItems); const onItemsChange = useCallback( (changes: ChangesType[]) => setItems((items) => applyChangesFunction(changes, items)), [] ); return [items, setItems, onItemsChange]; }; } export const useNodesState = createUseItemsState(applyNodeChanges as ApplyChanges); export const useEdgesState = createUseItemsState(applyEdgeChanges as ApplyChanges);