- React: Declarative, re-renders on state change
- Three.js: Imperative, mutates objects directly
Two Sources of Truth
| State Location | Purpose | What It Controls |
|---|---|---|
| React Context (AppContext) | UI state | What components render, form values, UI toggles |
| GraphStateManager | Rendering state | What Three.js displays, node positions, visibility |
useGraph3D hook is the bridge that synchronizes these two state sources.
State Flow
1
User Action
User clicks node, changes depth, toggles filter
2
Dual Update
AppContext dispatch() updates React state; GraphService method updates rendering state
3
useGraph3D Sync
Hook detects React state change and syncs to GraphStateManager
4
Render
React components re-render; Three.js updates canvas
AppContext (React State)
Manages all UI-related state usinguseReducer pattern:
| State Property | Type | Purpose |
|---|---|---|
selectedNodeIds | Set<string> | Currently selected node IDs |
selectedNode | object | Primary selected node (for detail panel) |
selectionDepth | number | BFS depth expansion (1-5) |
selectionMode | string | ’new’, ‘add’, ‘subtract’, ‘intersect’ |
nodeTypeFilter.hiddenTypes | Set<string> | Node types to hide |
edgeTypeFilter.hiddenTypes | Set<string> | Edge types to hide |
showClassLabels | boolean | Show labels on class nodes |
canUndoSelection | boolean | Undo available flag |
canRedoSelection | boolean | Redo available flag |
GraphStateManager (Rendering State)
Centralized mutable state for Three.js rendering:| State Property | Type | Purpose |
|---|---|---|
graphInstance | ForceGraph3D | Three.js graph instance |
allNodes | array | Complete node dataset |
allLinks | array | Complete edge dataset |
selectedNodeIds | Set<string> | Multi-select node IDs |
selectionDepth | number | BFS depth for filtering |
instancedRenderer | InstancedNodeRenderer | GPU instanced rendering |
Synchronization Pattern
When state affects both UI and rendering:Correct
- Update React Context (dispatch)
- useEffect in useGraph3D detects change
- useEffect syncs to GraphStateManager
- useEffect calls service method
Wrong
- Only updating React Context (UI updates, render doesn’t)
- Only updating GraphStateManager (render updates, UI doesn’t)
- Calling service method directly without context update
Critical useEffects in useGraph3D
| Dependency | Action | Purpose |
|---|---|---|
selectedNodeIds, selectionDepth, edgeTypeFilter | applyUnifiedFilter() | Update visibility |
nodeTypeFilter | updateTypeFilter() | Hide/show node types |
nodes, edges | updateGraphData() | Load new data |
showClassLabels, labelSize | Update label settings | Visual changes |