Adding Interactivity to Your Flow
This guide shows how to create an interactive flow in Reflex, allowing you to select, drag, and connect nodes and edges.
Define the State
We start by defining the nodes and edges of the flow. The FlowState class holds the nodes and edges as state variables and includes event handlers to respond to changes.
ExpandCollapse
Add Event Handlers
Event handlers allow the flow to respond to user interactions such as dragging nodes, updating edges, or creating new connections.
- set_nodes updates nodes when they are moved or edited.
- set_edges updates edges when they are modified or deleted.
Note that these are plain setters — they receive the already-updated list. The change-application logic lives in the component wiring, shown next.
Render the Interactive Flow
Finally, we render the flow using rxe.flow, passing in the state and event handlers. Additional UI features include zoom/pan controls, a background grid, and a mini-map for navigation.
ExpandCollapse
on_nodes_changefires when nodes are dragged, selected, resized, or removed.on_edges_changefires when edges are selected or removed.on_connectfires when the user drags a connection between two handles;rxe.flow.util.add_edgebuilds the new edge list from the connection.
Make sure to set the height and width of the container around the flow — the flow fills its parent, so without explicit dimensions it will not be visible.
Controlled vs. Uncontrolled Flows
Passing nodes and edges makes the flow controlled: your state is the source of truth, and the canvas renders exactly what the state contains. A controlled flow must wire on_nodes_change and on_edges_change as shown above, otherwise user interactions (dragging, selecting, deleting) are discarded.
Passing only default_nodes and default_edges makes the flow uncontrolled: the component manages changes internally, but your state never learns about them.
Where Changes Get Applied
rxe.flow.util.apply_node_changes and rxe.flow.util.apply_edge_changes must be used inside of component code — in the lambda wired to on_nodes_change / on_edges_change — and never inside of state code. They evaluate on the client and produce the updated list, which is then passed to a plain setter event handler:
Do not call these utilities from within an @rx.event handler; the state side should only receive and store the resulting list.