Source on GitHub (opens in a new tab)

This hook can be used to subscribe to internal state changes of the React Flow component. The useStore hook is re-exported from the Zustand (opens in a new tab) state management library, so you should check out their docs for more details.

This hook should only be used if there is no other way to access the internal state. For many of the common use cases, there are dedicated hooks available such as useReactFlow, useViewport, etc.

import { ReactFlow, useStore } from '@xyflow/react';
const nodesLengthSelector = (state) =>
  state.nodes.length || 0;
const NodesLengthDisplay = () => {
  const nodesLength = useStore(nodesLengthSelector);
  return <div>The current number of nodes is: {nodesLength}</div>;
function Flow() {
  return (
    <ReactFlow nodes={[...]}>
      <NodesLengthDisplay />

This example computes the number of nodes eagerly. Whenever the number of nodes in the flow changes, the <NodesLengthDisplay /> component will re-render. This is in contrast to the example in the useStoreApi hook that only computes the number of nodes when a button is clicked.

Choosing whether to calculate values on-demand or to subscribe to changes as they happen is a bit of a balancing act. On the one hand, putting too many heavy calculations in an event handler can make your app feel sluggish or unresponsive. On the other hand, computing values eagerly can lead to slow or unnecessary re-renders.

We make both this hook and useStoreApi available so that you can choose the approach that works best for your use-case.


(state: ReactFlowState) => T
A selector function that returns a slice of the flow's internal state. Extracting or transforming just the state you need is a good practice to avoid unnecessary re-renders.
(prev: T, next: T) => boolean
A function to compare the previous and next value. This is incredibly useful for preventing uneccessary re-renders. Good sensible defaults are using or importing zustand/shaddlow, but you can be as granular as you like.


Triggering store actions

You can manipulate the internal React Flow state by triggering internal actions through the useStore hook. These actions are already used internally throughout the library, but you can also use them to implement custom functionality.

import { useStore } from '@xyflow/react';
const setMinZoomSelector = (state) => state.setMinZoom;
function MinZoomSetter() {
  const setMinZoom = useStore(setMinZoomSelector);
  return <button onClick={() => setMinZoom(6)}>set min zoom</button>;


This hook can be typed by typing the selector function. See this section in our Typescript guide for more information.

const nodes = useStore((s: ReactFlowState<CustomNodeType>) => ({
  nodes: s.nodes,


  • You should define your store selector function outside of the component that uses it, or use React's useCallback hook to memoize the function. Not doing this can incur a slight performance penalty.