Skip to Content
LearnAdvanced UseHooks and Providers

Hooks and Providers

React Flow provides several hooks and a context provider for you to enhance the functionality of your flow. These tools help you to manage state, access internal methods, and create custom components more effectively.

ReactFlowProvider

The ReactFlowProvider is a context provider that allows you to access the internal state of the flow, such as nodes, edges, and viewport, from anywhere in your component tree even outside the ReactFlow component. It is typically used at the top level of your application.

There are several cases where you might need to use the ReactFlowProvider component:

  • Many of the hooks we provide rely on this component to work.
  • You want to access the internal state of the flow outside of the ReactFlow component.
  • You are working with multiple flows on a page.
  • You are using a client-side router.
/* xyflow theme files. Delete these to start from our base */ .react-flow { --xy-background-color: #f7f9fb; /* Custom Variables */ --xy-theme-selected: #f57dbd; --xy-theme-hover: #c5c5c5; --xy-theme-edge-hover: black; --xy-theme-color-focus: #e8e8e8; /* Built-in Variables see https://reactflow.dev/learn/customization/theming */ --xy-node-border-default: 1px solid #ededed; --xy-node-boxshadow-default: 0px 3.54px 4.55px 0px #00000005, 0px 3.54px 4.55px 0px #0000000d, 0px 0.51px 1.01px 0px #0000001a; --xy-node-border-radius-default: 8px; --xy-handle-background-color-default: #ffffff; --xy-handle-border-color-default: #aaaaaa; --xy-edge-label-color-default: #505050; --xy-node-background-color-default: #ffffff; --xy-theme-panel-bg: #ffffff; --xy-theme-panel-text: #111827; --xy-theme-resize-handle-bg: #ffffff; --xy-theme-focus-border: #d9d9d9; --xy-theme-muted-bg: #f3f4f6; --xy-theme-subtle-border: #d1d5db; } .react-flow.dark { --xy-background-color: #101012; --xy-node-background-color-default: #1a1b1e; --xy-node-border-default: 1px solid #303238; --xy-handle-background-color-default: #141519; --xy-handle-border-color-default: #5a5d66; --xy-edge-label-color-default: #e6e7ea; --xy-theme-hover: #7a7d86; --xy-theme-edge-hover: #f3f4f6; --xy-theme-panel-bg: #141519; --xy-theme-panel-text: #f3f4f6; --xy-theme-resize-handle-bg: #141519; --xy-theme-focus-border: #5f6470; --xy-theme-muted-bg: #24262c; --xy-theme-subtle-border: #3f434c; --xy-node-boxshadow-default: none; --xy-theme-color-focus: #4b4e57; --color-background: #1a1b1e; --color-hover-bg: #24262c; --color-disabled: #8b9099; } .react-flow { background-color: var(--xy-background-color); } /* Customizing Default Theming */ .react-flow__node { box-shadow: var(--xy-node-boxshadow-default); border-radius: var(--xy-node-border-radius-default); background-color: var(--xy-node-background-color-default); display: flex; justify-content: center; align-items: center; text-align: center; padding: 10px; font-size: 12px; flex-direction: column; border: var(--xy-node-border-default); color: var(--xy-node-color, var(--xy-node-color-default)); } .react-flow__node.selectable:focus { box-shadow: 0px 0px 0px 4px var(--xy-theme-color-focus); border-color: var(--xy-theme-focus-border); } .react-flow__node.selectable:focus:active { box-shadow: var(--xy-node-boxshadow-default); } .react-flow__node.selectable:hover, .react-flow__node.draggable:hover { border-color: var(--xy-theme-hover); } .react-flow__node.selectable.selected { border-color: var(--xy-theme-selected); box-shadow: var(--xy-node-boxshadow-default); } .react-flow__node-group { background-color: rgba(207, 182, 255, 0.4); border-color: #9e86ed; } .react-flow.dark .react-flow__node-group { background-color: rgba(123, 107, 148, 0.22); border-color: #7b6b94; } .react-flow__edge.selectable:hover .react-flow__edge-path, .react-flow__edge.selectable.selected .react-flow__edge-path { stroke: var(--xy-theme-edge-hover); } .react-flow__handle { background-color: var(--xy-handle-background-color-default); } .react-flow__handle.connectionindicator:hover { pointer-events: all; border-color: var(--xy-theme-edge-hover); background-color: var(--xy-handle-background-color-default); } .react-flow__handle.connectionindicator:focus, .react-flow__handle.connectingfrom, .react-flow__handle.connectingto { border-color: var(--xy-theme-edge-hover); } .react-flow__node-resizer { border-radius: 0; border: none; } .react-flow__resize-control.handle { background-color: var(--xy-theme-resize-handle-bg); border-color: #9e86ed; border-radius: 0; width: 5px; height: 5px; } /* Custom Example CSS - This CSS is to improve the example experience. You can remove it if you want to use the default styles. New Theme Classes: .xy-theme__button - Styles for buttons. .xy-theme__input - Styles for text inputs. .xy-theme__checkbox - Styles for checkboxes. .xy-theme__select - Styles for dropdown selects. .xy-theme__label - Styles for labels. Use these classes to apply consistent theming across your components. */ :root { --color-primary: #ff0073; --color-background: #fefefe; --color-hover-bg: #f6f6f6; --color-disabled: #76797e; } .xy-theme__button-group { display: flex; align-items: center; .xy-theme__button:first-child { border-radius: 100px 0 0 100px; } .xy-theme__button:last-child { border-radius: 0 100px 100px 0; margin: 0; } } /* Custom Button Styling */ .xy-theme__button { display: inline-flex; align-items: center; justify-content: center; height: 2.5rem; padding: 0 1rem; border-radius: 100px; border: 1px solid var(--color-primary); background-color: var(--color-background); color: var(--color-primary); transition: background-color 0.2s ease, border-color 0.2s ease; box-shadow: var(--xy-node-boxshadow-default); cursor: pointer; } .xy-theme__button.active { background-color: var(--color-primary); color: white; border-color: var(--color-primary); } .xy-theme__button.active:hover, .xy-theme__button.active:active { background-color: var(--color-primary); opacity: 0.9; } .xy-theme__button:hover { background-color: var(--xy-controls-button-background-color-hover-default); } .xy-theme__button:active { background-color: var(--color-hover-bg); } .xy-theme__button:disabled { color: var(--color-disabled); opacity: 0.8; cursor: not-allowed; border: 1px solid var(--color-disabled); } .xy-theme__button > span { margin-right: 0.2rem; } /* Add gap between adjacent buttons */ .xy-theme__button + .xy-theme__button { margin-left: 0.3rem; } /* Example Input Styling */ .xy-theme__input { padding: 0.5rem 0.75rem; border: 1px solid var(--color-primary); border-radius: 7px; background-color: var(--color-background); transition: background-color 0.2s ease, border-color 0.2s ease; font-size: 1rem; color: var(--xy-theme-panel-text); } .xy-theme__input:focus { outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 2px rgba(255, 0, 115, 0.3); } /* Specific Checkbox Styling */ .xy-theme__checkbox { appearance: none; -webkit-appearance: none; width: 1.25rem; height: 1.25rem; border-radius: 7px; border: 2px solid var(--color-primary); background-color: var(--color-background); transition: background-color 0.2s ease, border-color 0.2s ease; cursor: pointer; display: inline-block; vertical-align: middle; margin-right: 0.5rem; } .xy-theme__checkbox:checked { background-color: var(--color-primary); border-color: var(--color-primary); } .xy-theme__checkbox:focus { outline: none; box-shadow: 0 0 0 2px rgba(255, 0, 115, 0.3); } /* Dropdown Styling */ .xy-theme__select { padding: 0.5rem 0.75rem; border: 1px solid var(--color-primary); border-radius: 50px; background-color: var(--color-background); transition: background-color 0.2s ease, border-color 0.2s ease; font-size: 1rem; color: var(--xy-theme-panel-text); margin-right: 0.5rem; box-shadow: var(--xy-node-boxshadow-default); } .xy-theme__select:focus { outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 2px rgba(255, 0, 115, 0.3); } .xy-theme__label { margin-top: 10px; margin-bottom: 3px; display: inline-block; color: var(--xy-theme-panel-text); }

useReactFlow

The useReactFlow hook provides access to the ReactFlowInstance and its methods. It allows you to manipulate nodes, edges, and the viewport programmatically.

This example illustrates how to use the useReactFlow hook.

/* xyflow theme files. Delete these to start from our base */ .react-flow { --xy-background-color: #f7f9fb; /* Custom Variables */ --xy-theme-selected: #f57dbd; --xy-theme-hover: #c5c5c5; --xy-theme-edge-hover: black; --xy-theme-color-focus: #e8e8e8; /* Built-in Variables see https://reactflow.dev/learn/customization/theming */ --xy-node-border-default: 1px solid #ededed; --xy-node-boxshadow-default: 0px 3.54px 4.55px 0px #00000005, 0px 3.54px 4.55px 0px #0000000d, 0px 0.51px 1.01px 0px #0000001a; --xy-node-border-radius-default: 8px; --xy-handle-background-color-default: #ffffff; --xy-handle-border-color-default: #aaaaaa; --xy-edge-label-color-default: #505050; --xy-node-background-color-default: #ffffff; --xy-theme-panel-bg: #ffffff; --xy-theme-panel-text: #111827; --xy-theme-resize-handle-bg: #ffffff; --xy-theme-focus-border: #d9d9d9; --xy-theme-muted-bg: #f3f4f6; --xy-theme-subtle-border: #d1d5db; } .react-flow.dark { --xy-background-color: #101012; --xy-node-background-color-default: #1a1b1e; --xy-node-border-default: 1px solid #303238; --xy-handle-background-color-default: #141519; --xy-handle-border-color-default: #5a5d66; --xy-edge-label-color-default: #e6e7ea; --xy-theme-hover: #7a7d86; --xy-theme-edge-hover: #f3f4f6; --xy-theme-panel-bg: #141519; --xy-theme-panel-text: #f3f4f6; --xy-theme-resize-handle-bg: #141519; --xy-theme-focus-border: #5f6470; --xy-theme-muted-bg: #24262c; --xy-theme-subtle-border: #3f434c; --xy-node-boxshadow-default: none; --xy-theme-color-focus: #4b4e57; --color-background: #1a1b1e; --color-hover-bg: #24262c; --color-disabled: #8b9099; } .react-flow { background-color: var(--xy-background-color); } /* Customizing Default Theming */ .react-flow__node { box-shadow: var(--xy-node-boxshadow-default); border-radius: var(--xy-node-border-radius-default); background-color: var(--xy-node-background-color-default); display: flex; justify-content: center; align-items: center; text-align: center; padding: 10px; font-size: 12px; flex-direction: column; border: var(--xy-node-border-default); color: var(--xy-node-color, var(--xy-node-color-default)); } .react-flow__node.selectable:focus { box-shadow: 0px 0px 0px 4px var(--xy-theme-color-focus); border-color: var(--xy-theme-focus-border); } .react-flow__node.selectable:focus:active { box-shadow: var(--xy-node-boxshadow-default); } .react-flow__node.selectable:hover, .react-flow__node.draggable:hover { border-color: var(--xy-theme-hover); } .react-flow__node.selectable.selected { border-color: var(--xy-theme-selected); box-shadow: var(--xy-node-boxshadow-default); } .react-flow__node-group { background-color: rgba(207, 182, 255, 0.4); border-color: #9e86ed; } .react-flow.dark .react-flow__node-group { background-color: rgba(123, 107, 148, 0.22); border-color: #7b6b94; } .react-flow__edge.selectable:hover .react-flow__edge-path, .react-flow__edge.selectable.selected .react-flow__edge-path { stroke: var(--xy-theme-edge-hover); } .react-flow__handle { background-color: var(--xy-handle-background-color-default); } .react-flow__handle.connectionindicator:hover { pointer-events: all; border-color: var(--xy-theme-edge-hover); background-color: var(--xy-handle-background-color-default); } .react-flow__handle.connectionindicator:focus, .react-flow__handle.connectingfrom, .react-flow__handle.connectingto { border-color: var(--xy-theme-edge-hover); } .react-flow__node-resizer { border-radius: 0; border: none; } .react-flow__resize-control.handle { background-color: var(--xy-theme-resize-handle-bg); border-color: #9e86ed; border-radius: 0; width: 5px; height: 5px; } /* Custom Example CSS - This CSS is to improve the example experience. You can remove it if you want to use the default styles. New Theme Classes: .xy-theme__button - Styles for buttons. .xy-theme__input - Styles for text inputs. .xy-theme__checkbox - Styles for checkboxes. .xy-theme__select - Styles for dropdown selects. .xy-theme__label - Styles for labels. Use these classes to apply consistent theming across your components. */ :root { --color-primary: #ff0073; --color-background: #fefefe; --color-hover-bg: #f6f6f6; --color-disabled: #76797e; } .xy-theme__button-group { display: flex; align-items: center; .xy-theme__button:first-child { border-radius: 100px 0 0 100px; } .xy-theme__button:last-child { border-radius: 0 100px 100px 0; margin: 0; } } /* Custom Button Styling */ .xy-theme__button { display: inline-flex; align-items: center; justify-content: center; height: 2.5rem; padding: 0 1rem; border-radius: 100px; border: 1px solid var(--color-primary); background-color: var(--color-background); color: var(--color-primary); transition: background-color 0.2s ease, border-color 0.2s ease; box-shadow: var(--xy-node-boxshadow-default); cursor: pointer; } .xy-theme__button.active { background-color: var(--color-primary); color: white; border-color: var(--color-primary); } .xy-theme__button.active:hover, .xy-theme__button.active:active { background-color: var(--color-primary); opacity: 0.9; } .xy-theme__button:hover { background-color: var(--xy-controls-button-background-color-hover-default); } .xy-theme__button:active { background-color: var(--color-hover-bg); } .xy-theme__button:disabled { color: var(--color-disabled); opacity: 0.8; cursor: not-allowed; border: 1px solid var(--color-disabled); } .xy-theme__button > span { margin-right: 0.2rem; } /* Add gap between adjacent buttons */ .xy-theme__button + .xy-theme__button { margin-left: 0.3rem; } /* Example Input Styling */ .xy-theme__input { padding: 0.5rem 0.75rem; border: 1px solid var(--color-primary); border-radius: 7px; background-color: var(--color-background); transition: background-color 0.2s ease, border-color 0.2s ease; font-size: 1rem; color: var(--xy-theme-panel-text); } .xy-theme__input:focus { outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 2px rgba(255, 0, 115, 0.3); } /* Specific Checkbox Styling */ .xy-theme__checkbox { appearance: none; -webkit-appearance: none; width: 1.25rem; height: 1.25rem; border-radius: 7px; border: 2px solid var(--color-primary); background-color: var(--color-background); transition: background-color 0.2s ease, border-color 0.2s ease; cursor: pointer; display: inline-block; vertical-align: middle; margin-right: 0.5rem; } .xy-theme__checkbox:checked { background-color: var(--color-primary); border-color: var(--color-primary); } .xy-theme__checkbox:focus { outline: none; box-shadow: 0 0 0 2px rgba(255, 0, 115, 0.3); } /* Dropdown Styling */ .xy-theme__select { padding: 0.5rem 0.75rem; border: 1px solid var(--color-primary); border-radius: 50px; background-color: var(--color-background); transition: background-color 0.2s ease, border-color 0.2s ease; font-size: 1rem; color: var(--xy-theme-panel-text); margin-right: 0.5rem; box-shadow: var(--xy-node-boxshadow-default); } .xy-theme__select:focus { outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 2px rgba(255, 0, 115, 0.3); } .xy-theme__label { margin-top: 10px; margin-bottom: 3px; display: inline-block; color: var(--xy-theme-panel-text); }
Last updated on