Uncaught TypeError: node is undefined when using custom reducer
Pavinati opened this issue · 5 comments
Switching from demoMode true
to false
and using a custom update logic crashes the Editor
To Reproduce
- Setup a minimal working example with
demoMode: true
- Write your custom reducer
- use
demoMode: false
and apply your reducer to theonChange
callback - add a new node to the editor
Expected behavior
The code executes the reducer, a new state is produced and the editor updates
Setup
- Ubuntu 20.04
- Firefox 80.0
- Node 14
- React + ES6
Additional context
Code taken from my example
const reducer = (nodes, action) => {
switch (action.type) {
case 'NodeCreated':
return nodes.push(action.node);
// other cases handling
default:
return nodes;
}
};
export default () => {
const [nodes, updateNodes] = useReducer(reducer, []);
return (
<div className="flow-editor-wrapper">
<div className="flow-menu">
{ /* same as demo example */ }
</div>
<Editor
nodes={nodes}
config={{
resolver,
onChanged: updateNodes,
connectionType: 'bezier',
grid: true,
demoMode: false,
direction: 'we',
}}
/>
</div>
);
}
Thank you for posting that issue. I try to investigate this the next days.
To be honest I am not a expert in the useReducer
approach, but
I think you mixed up the onChanged
callback with the reducer function.
Please have a look at the example code using redux:
https://github.com/lochbrunner/react-flow-editor/tree/master/example/redux
You have to set onChanged
to a redux action not a reducer.
Be aware that 'NodeCreated'
et. al. are the types of the payload of the action you registered for all editor actions:
export const reducer: Reducer<RootState> =
(state: RootState = {nodes: [] },
action: Action<{}|ChangeAction>) => {
if (action.type === Actions.EDITOR_UPDATES) {
const payload = action.payload as ChangeAction;
if (payload.type === 'NodeCreated') {
state.nodes.push(payload.node);
}
}
}
Sadly i'm not using Redux, just ES6 + react. Didn't see in the project description that redux was required.
By the way, the function you posted behaves similarly to what mine does: takes 2 parameters, the state and the event.
Performs some action depending on the event type, and updates the state
The library does not require redux
. Sorry for misunderstanding your code snippet.
But I think the outcome of useReducer
might not be suitable as you are using it for the callback here.
Let me have a look tomorrow. We will definitively find a solution for your case.
Maybe we have to add another example :D
OK I found at least two issues in your code:
Do it the functional style!
the push
method does not return what you expect
- return nodes.push(action.node);
+ return [...nodes, action.node];
Decouple the events!
- onChanged: updateNodes,
+ onChanged: (data) => setImmediate(() => updateNodes(data)),
I hope this works for you!
(At least this works for me)