Description
sendParent invokes event handler twice on parent machine
Expected Result
Event handler on parent machine should only be invoked once.
Actual Result
Event handler on parent is invoked two times
Reproduction
The
sendParent(ctx => ({ type: "TODO.COMMIT", todo: ctx }))
in the todoMachine.js will invoke "TODO.COMMIT" two times on todosMachine.js
The problem can be seen by adding a console.log in the handler for "TODO.COMMIT" in todosMachine.js
Additional context
Just tested this; it's only being called once. Can you create a simple reproduction?
https://codesandbox.io/s/xstate-todomvc-6nlwe
Added a console.log in todosMachine.js (line: 70-72)
If I edit an existing todo and press Enter, there will be two console.logs from the todosMachine
This happens because of this:
useEffect(() => {
todoRef.execute(state, {
focusInput() {
inputRef.current && inputRef.current.select();
}
});
}, [state, todoRef]);
state should not be used as a dependency of an effect - by doing this, actions of a particular state might get fired twice (once during regular execution and once in this effect).
Yeah, we'll have to edit the docs for this one, and introduce the useAction hook to make this safer.
This would be better done (right now) as:
useEffect(() => {
state.actions.forEach(action => {
if (action.type === 'focusInput') {
inputRef.current && inputRef.current.select();
}
});
}, [state]);
Thank you for the quick reply. That cleared up my confusion.
Most helpful comment
This happens because of this:
stateshould not be used as a dependency of an effect - by doing this, actions of a particularstatemight get fired twice (once during regular execution and once in this effect).