Last active
July 20, 2022 19:16
-
-
Save ganapativs/688026d7eb2c8a34f029b91379253251 to your computer and use it in GitHub Desktop.
Signup state machine using xstate
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState } from "react"; | |
import { Machine, assign } from "xstate"; | |
import { useMachine } from "@xstate/react"; | |
const signupUser = email => | |
new Promise((resolve, reject) => { | |
setTimeout(() => { | |
// resolve("You are signed up!"); | |
reject("Unable to sign you up :("); | |
}, 1000); | |
}); | |
const signUpMachine = Machine({ | |
id: "signup", | |
initial: "idle", | |
context: { | |
message: "" | |
}, | |
states: { | |
idle: { | |
on: { | |
SUBMIT: [ | |
{ | |
target: "loading", | |
// TODO - Validate email here | |
cond: (context, event) => event.data.email !== "", | |
actions: assign({ | |
message: (context, event) => "Signing you up..." | |
}) | |
}, | |
{ | |
target: "error", | |
actions: assign({ | |
message: (context, event) => "Please enter a valid email" | |
}) | |
} | |
] | |
} | |
}, | |
loading: { | |
invoke: { | |
id: "submitSignup", | |
src: (context, event) => signupUser(event.data.email), | |
onDone: { | |
target: "success", | |
actions: assign({ | |
message: (context, event) => event.data | |
}) | |
}, | |
onError: { | |
target: "error", | |
actions: assign({ | |
message: (context, event) => event.data | |
}) | |
} | |
} | |
}, | |
success: { | |
type: "final" | |
}, | |
error: { | |
on: { | |
SUBMIT: [ | |
{ | |
target: "loading", | |
// TODO - Validate email here | |
cond: (context, event) => event.data.email !== "", | |
actions: assign({ | |
message: (context, event) => "Signing you up..." | |
}) | |
}, | |
// Incase user removes email | |
{ | |
target: "error", | |
actions: assign({ | |
message: (context, event) => "Please enter a valid email" | |
}) | |
} | |
] | |
} | |
} | |
} | |
}); | |
function App() { | |
const [machine, send] = useMachine(signUpMachine); | |
const [form, updateForm] = useState({ email: "" }); | |
return ( | |
<div className="App"> | |
{machine.context.message ? machine.context.message : null} | |
{!machine.matches("success") ? ( | |
<form | |
onSubmit={e => { | |
e.preventDefault(); | |
send({ type: "SUBMIT", data: form }); | |
}} | |
> | |
<input | |
type="email" | |
name="email" | |
onChange={e => { | |
updateForm({ ...form, email: e.target.value }); | |
}} | |
/> | |
<button type="submit">Submit</button> | |
</form> | |
) : null} | |
</div> | |
); | |
} | |
export default App; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment