Description
I create a machine like so: const foo = Machine({/*...*/}); and use it in my react component like so: const [current, send] = useMachine(foo)
when I start up the app, I get console warnings in the browser about calling .start(), but I can not find any documentation on where to call .start().
Expected Result
No console warnings
Actual Result
Browser console says
Warning: Event "LOAD" was sent to uninitialized service "status" and is deferred. Make sure .start() is called for this service.
Event: {"type":"LOAD"}
Reproduction
Additional context
I am using xstate version 4.9.1, and @xstate/react version 0.8.1.
The machine is interpreted and the service started for you. So you do not need to do it.
It must have something to do with the React render cycle. In the useMaschine hook the service is is started and assigned to a React ref. I know that a useEffect hook execution is scheduled after the render is complete but am not really sure about the scheduling of useRef. In general you should avoid to call non-render side-effect in your function body as it can cause bugs duo to scheduling. This is one of them.
Your send({ type: "LOAD" }) is such a side-effect. It tried the most obvious thing and wrap it in a useEffect. With that the warning is gone and everything works as expected.
Only do side-effects in useEffect, and you'll see the error go away.
const [current, send] = useMachine(machine);
- if (current.matches("initial")) send({ type: "LOAD" });
+ React.useEffect(() => {
+ if (current.matches("initial")) send({ type: "LOAD" });
+ }, [current, send])
Most helpful comment
Only do side-effects in
useEffect, and you'll see the error go away.