Use an XState Machine with React

XState gives you the tools to take control over the state of your UI. When you’ve got it under control, you can build interfaces that provide a predictable and delightful user experience.

Let’s look at how to integrate XState into a React app.

There …


This content originally appeared on DEV Community and was authored by Josh Branchaud

XState gives you the tools to take control over the state of your UI. When you've got it under control, you can build interfaces that provide a predictable and delightful user experience.

Let's look at how to integrate XState into a React app.

There are a bunch of well-constructed XState machines available to directly copy into your project from XState Catalogue. For instance, I can interact with and then grab the Confirmation Dialog machine with the 'Copy' button.

Alt Text

I'll then paste that machine definition into something like confirmMachine.js. XState is framework agnostic, so there is nothing about this machine, on its own, that has anything to do with React or Vue or Svelte or whatever. I do want to use this within a React app, so I then need to grab @xstate/react. XState's React "bindings" come with a useMachine hook.

An Example

Here is what that will look like.

import * as React from "react";
import { useMachine } from "@xstate/react";
import confirmMachine from "./confirmMachine";
import Dialog from "./dialog";

export default function App() {
  const [current, send] = useMachine(confirmMachine);

  return (
    <div className="App">
      <Dialog
        message="Are you sure you want to delete something?"
        {/* other props ... */}
      />
      {/* other stuff */}
    </div>
  )
}

The useMachine call both interprets and starts up the machine service. This hook gives you two values as an array. The current value is everything about the current state of the machine. The send is a function for dispatching transitions between machine states.

The Current State of the Machine

With current I can figure out the current state of the machine to determine whether or not I should be showing the dialog. current.value will tell me what state the machine is in.

I can also get access to any error message that comes from the machine.

import * as React from "react";
import { useMachine } from "@xstate/react";
import confirmMachine from "./confirmMachine";
import Dialog from "./dialog";

export default function App() {
  const [current, send] = useMachine(confirmMachine);

  const showDialog = current.value !== "closed";

  return (
    <div className="App">
      <Dialog
        message="Are you sure you want to delete something?"
        showDialog={showDialog}
        errorMessage={current.context.errorMessage}
      />
      {/* other stuff */}
    </div>
  )
}

Notice I check current.value !== "closed" to determine whether or not the dialog should be showing.

Moving Between States with Send

I can now incorporate the send function into some handlers so that users can interact with the dialog. I'll create a handler for opening, closing, and confirming the dialog.

import * as React from "react";
import { useMachine } from "@xstate/react";
import confirmMachine from "./confirmMachine";
import Dialog from "./dialog";

export default function App() {
  const [current, send] = useMachine(confirmMachine);

  const deleteAction = () => { /* ... */ };

  const showDialog = current.value !== "closed";
  const open = () => {
    send({ type: "OPEN_DIALOG", action: deleteAction });
  };
  const close = () => {
    send("CANCEL");
  };
  const confirm = () => {
    send("CONFIRM");
  };

  return (
    <div className="App">
      <Dialog
        message="Are you sure you want to delete something?"
        handleConfirm={confirm}
        handleClose={close}
        showDialog={showDialog}
        errorMessage={current.context.errorMessage}
      />
      {/* other stuff */}
      <button onClick={open}>Delete Something</button>
    </div>
  )
}

The open handler when called will transition the machine to open.idle using the OPEN_DIALOG event. It also includes an action which will be called if the dialog is confirmed. When triggered, this will cause the showDialog value to evaluate to true. This handler is wired up to some element outside of the dialog, in this case a button.

The close handler is passed to the dialog. When called this sends the CANCEL event to the machine. That will transition the machine back into the closed state. This change will cause the showDialog value to evaluate back to false. Any user action that should dismiss the dialog will trigger this handler.

Once the dialog is open, the user can confirm the dialog's prompt by clicking a 'Confirm' button. This will call the confirm handler which will send the CONFIRM event to the machine. When the machine receives this event it will trigger the action given on OPEN_DIALOG.

Wrapping Up

There are more details to this specific machine. Depending on whether the action's promise resolves or rejects, the machine will take a different course of action. That's an exercise for the reader or the subject of another post.

At this point, we have explored the enough of XState in a React context that you can start using the two together. If you'd like you can start by interacting with and remixing the codesandbox example I used for this post.

There are a lot of moving parts when getting started with XState, so if you have questions about what was covered here, feel free to drop me a note on twitter.

If you enjoy my writing, consider joining my newsletter.

Cover photo by Ball Park Brand on Unsplash


This content originally appeared on DEV Community and was authored by Josh Branchaud


Print Share Comment Cite Upload Translate Updates
APA

Josh Branchaud | Sciencx (2021-05-08T22:21:21+00:00) Use an XState Machine with React. Retrieved from https://www.scien.cx/2021/05/08/use-an-xstate-machine-with-react/

MLA
" » Use an XState Machine with React." Josh Branchaud | Sciencx - Saturday May 8, 2021, https://www.scien.cx/2021/05/08/use-an-xstate-machine-with-react/
HARVARD
Josh Branchaud | Sciencx Saturday May 8, 2021 » Use an XState Machine with React., viewed ,<https://www.scien.cx/2021/05/08/use-an-xstate-machine-with-react/>
VANCOUVER
Josh Branchaud | Sciencx - » Use an XState Machine with React. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/05/08/use-an-xstate-machine-with-react/
CHICAGO
" » Use an XState Machine with React." Josh Branchaud | Sciencx - Accessed . https://www.scien.cx/2021/05/08/use-an-xstate-machine-with-react/
IEEE
" » Use an XState Machine with React." Josh Branchaud | Sciencx [Online]. Available: https://www.scien.cx/2021/05/08/use-an-xstate-machine-with-react/. [Accessed: ]
rf:citation
» Use an XState Machine with React | Josh Branchaud | Sciencx | https://www.scien.cx/2021/05/08/use-an-xstate-machine-with-react/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.