Troubleshooting
This guide contains warnings and errors that can occur when using React Flow. We are also adding common questions and pitfalls that we collect from our Discord Server, Github Issues and Github Discussions.
Warning: Seems like you have not used zustand provider as an ancestor
This usually happens when:
A: You have two different version of @reactflow/core installed.
B: You are trying to access the internal React Flow state outside of the React Flow context.
Solution for A
Update reactflow and @reactflow/node-resizer (in case you are using it), remove node_modules and package-lock.json and reinstall the dependencies.
Solution for B
A possible solution is to wrap your component with a <ReactFlowProvider />
or move the code that is accessing the state inside a child of your React Flow instance.
import { ReactFlow } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
function FlowWithoutProvider(props) {
// cannot access the state here
const reactFlowInstance = useReactFlow();
return <ReactFlow {...props} />;
}
export default FlowWithoutProvider;
import { ReactFlow, ReactFlowProvider } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
function Flow(props) {
// still cannot access the state here
// only child components of this component can access the state
const reactFlowInstance = useReactFlow();
return (
<ReactFlowProvider>
<ReactFlow {...props} />
</ReactFlowProvider>
);
}
export default FlowWithProvider;
As soon as you want to access the internal state of React Flow (for example by using the useReactFlow
hook), you need to wrap your component with a <ReactFlowProvider />
. Here the wrapping is done outside of the component:
import { ReactFlow, ReactFlowProvider } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
function Flow(props) {
// you can access the internal state here
const reactFlowInstance = useReactFlow();
return <ReactFlow {...props} />;
}
// wrapping with ReactFlowProvider is done outside of the component
function FlowWithProvider(props) {
return (
<ReactFlowProvider>
<Flow {...props} />
</ReactFlowProvider>
);
}
export default FlowWithProvider;
It looks like you have created a new nodeTypes or edgeTypes object. If this wasn’t
on purpose please define the nodeTypes/edgeTypes outside of the component or memoize them.
This warning appears when the nodeTypes
or edgeTypes
properties change after the initial render. The nodeTypes
or edgeTypes
should only be changed dynamically in very rare cases. Usually they are defined once with all the types that you are using in your application. It can happen easily that you are defining the nodeTypes or edgeTypes object inside of your component render function, which will cause React Flow to re-render every time your component re-renders.
import { ReactFlow } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import MyCustomNode from './MyCustomNode';
function Flow(props) {
// new object being created on every render
// causing unneccessary re-renders
const nodeTypes = {
myCustomNode: MyCustomNode,
};
return <ReactFlow nodeTypes={nodeTypes} />;
}
export default Flow;
import { ReactFlow } from '@xyflow/react';
import MyCustomNode from './MyCustomNode';
// defined outside of the component
const nodeTypes = {
myCustomNode: MyCustomNode,
};
function Flow(props) {
return <ReactFlow nodeTypes={nodeTypes} />;
}
export default Flow;
You can use this if you want to change your nodeTypes dynamically without causing unneccessary re-renders.
import { useMemo } from 'react';
import { ReactFlow } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import MyCustomNode from './MyCustomNode';
function Flow(props) {
const nodeTypes = useMemo(
() => ({
myCustomNode: MyCustomNode,
}),
[],
);
return <ReactFlow nodeTypes={nodeTypes} />;
}
export default Flow;
Node type not found. Using fallback type “default”.
This usually happens when you are specifying a custom node type for one of your nodes but not passing the correct nodeTypes property to React Flow. The string for the type option of your custom node needs to be exactly the same as the key of the nodeTypes object.
import { ReactFlow } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import MyCustomNode from './MyCustomNode';
const nodes = [
{
id: 'mycustomnode',
type: 'custom',
// ...
},
];
function Flow(props) {
// nodeTypes property is missing, so React Flow cannot find the custom node component to render
return <ReactFlow nodes={nodes} />;
}
import { ReactFlow } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import MyCustomNode from './MyCustomNode';
const nodes = [
{
id: 'mycustomnode',
type: 'custom',
// ...
},
];
const nodeTypes = {
Custom: MyCustomNode,
};
function Flow(props) {
// node.type and key in nodeTypes object are not exactly the same (capitalized)
return <ReactFlow nodes={nodes} nodeTypes={nodeTypes} />;
}
import { ReactFlow } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
import MyCustomNode from './MyCustomNode';
const nodes = [
{
id: 'mycustomnode',
type: 'custom',
// ...
},
];
const nodeTypes = {
custom: MyCustomNode,
};
function Flow(props) {
return <ReactFlow nodes={nodes} nodeTypes={nodeTypes} />;
}
The React Flow parent container needs a width and a height to render the graph.
Under the hood, React Flow measures the parent DOM element to adjust the renderer. If you try to render React Flow in a regular div without a height, we cannot display the graph. If you encounter this warning, you need to make sure that your wrapper component has some CSS attached to it so that it gets a fixed height or inherits the height of its parent.
import { ReactFlow } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
function Flow(props) {
return (
<div>
<ReactFlow {...props} />
</div>
);
}
import { ReactFlow } from '@xyflow/react';
function Flow(props) {
return (
<div style={{ height: 800 }}>
<ReactFlow {...props} />
</div>
);
}
Only child nodes can use a parent extent.
This warning appears when you are trying to add the extent
option to a node that does not have a parent node. Depending on what you are trying to do, you can remove the extent
option or specify a parentNode
.
import { ReactFlow } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
const nodes = [
{
id: 'mycustomnode',
extent: 'parent',
// ...
},
];
function Flow(props) {
return <ReactFlow nodes={nodes} />;
}
const nodes = [
{
id: 'mycustomnode',
parentNode: 'someothernode',
extent: 'parent',
// ...
},
];
function Flow(props) {
return <ReactFlow nodes={nodes} />;
}
Can’t create edge. An edge needs a source and a target.
This happens when you do not pass a source
and a target
option to the edge object. Without the source and target, the edge cannot be rendered.
import { ReactFlow } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
const nodes = [
/* ... */
];
const edges = [
{
nosource: '1',
notarget: '2',
},
];
function Flow(props) {
return <ReactFlow nodes={nodes} edges={edges} />;
}
import { ReactFlow } from '@xyflow/react';
const nodes = [
/* ... */
];
const edges = [
{
source: '1',
target: '2',
},
];
function Flow(props) {
return <ReactFlow nodes={nodes} edges={edges} />;
}
The old edge with id=“some-id” does not exist.
This can happen when you are trying to reconnect an edge but the edge you want to update is already removed from the state. This is a very rare case. Please see the Reconnect Edge example for implementation details.
Couldn’t create edge for source/target handle id: “some-id”; edge id: “some-id”.
This can happen if you are working with multiple handles and a handle is not found by its id
property or if you haven’t updated the node internals after adding or removing handles programmatically. Please see the Custom Node Example for an example of working with multiple handles.
Marker type doesn’t exist.
This warning occurs when you are trying to specify a marker type that is not built into React Flow. The existing marker types are documented here.
Handle: No node id found.
This warning occurs when you try to use a <Handle />
component outside of a custom node component.
I get an error when building my app with webpack 4.
If you’re using webpack 4, you’ll likely run into an error like this:
ERROR in /node_modules/@reactflow/core/dist/esm/index.js 16:19
Module parse failed: Unexpected token (16:19)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
React Flow is a modern JavaScript code base and makes use of lots of newer JavaScript features. By default, webpack 4 does not transpile your code and it doesn’t know how to handle React Flow.
You need to add a number of babel plugins to your webpack config to make it work:
$ npm i --save-dev babel-loader@8.2.5 @babel/preset-env @babel/preset-react @babel/plugin-proposal-optional-chaining @babel/plugin-proposal-nullish-coalescing-operator
and configure the loader like this:
{
test: /node_modules[\/\\]@?reactflow[\/\\].*.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', "@babel/preset-react"],
plugins: [
"@babel/plugin-proposal-optional-chaining",
"@babel/plugin-proposal-nullish-coalescing-operator",
]
}
}
}
If you’re using webpack 5, you don’t need to do anything! React Flow will work out of the box.
Mouse events aren’t working consistently when my nodes contain a <canvas />
element.
If you’re using a <canvas />
element inside your custom node, you might run into
problems with seemingly-incorrect coordinates in mouse events from the cavnas.
React Flow uses CSS transforms to scale nodes as you zoom in and out. From the DOM’s perspective, however, the element is still the same size. This can cause problems if you have event listeners that want to calcuate the mouse position relative to the canvas element.
To remedy this in event handlers you control, you can scale your computed relative
position by 1 / zoom
where zoom
is the current zoom level of the flow. To get
the current zoom level, you can use the getZoom
method from the
useReactFlow
hook.