DEV Community

loading...

Discussion on: Use an XState Machine with React

Collapse
diasbruno profile image
Bruno Dias • Edited

Great article.

Two good things about state machine are to make invalid state irrepressible and define only valid transitions.

There are a lot of applications for this, and specially on the frontend, this is a great tool to make code more reliable and testable.

Collapse
jbranchaud profile image
Josh Branchaud Author

What are some applications of state machines that you've found most helpful?

Collapse
diasbruno profile image
Bruno Dias • Edited

Anything that can take 2, or more, distinct paths like wizard forms, processes...anything that looks like this...

Where each letter can be a component...

// React

const A = ({ state, setState, transformState }) => (
  <>
    <button ... onClick={() => setState([transformState(state, localState), B])}>Go to B</button>
    <button ... onClick={() => setState([transformState(state, localState), E])}>Go to E</button>
  </>
);

const B = ({ state, setState, transformState }) => (
  <button ... onClick={() => setState([transformState(state, localState), C])}>Go to C</button>
);

const C = ({ state, setState, transformState }) => (
  <button ... onClick={() => setState([transformState(state, localState), End])}>Go to End</button>
);

const D = ({ state, setState , transformState }) => (
  <button ... onClick={() => setState([transformState(state, localState), E])}>Go to E</button>
);

const E = ({ state, setState , transformState  }) => (
  <button ... onClick={() => setState([transformState(state, localState), End])}>Go to End</button>
);

const F = ({ state, setState , transformState  }) => (
  <button ... onClick={() => setState([transformState(state, localState), G])}>Go to G</button>
);

const G = ({ state, setState, transformState  }) => (
  <button ... onClick={() => setState([transformState(state, localState), End])}>Go to End</button>
);

const End = ({ state, setState }) => (
  <p>Fim!</p>
);

const DefaultStepComponent = ({ state, setState, transformState  }) => (
  <>
    <button ... onClick={() => setState([transformState(state), A])}>Go to A</button>
    <button ... onClick={() => setState([transformState(state), D])}>Go to D</button>
    <button ... onClick={() => setState([transformState(state), F])}>Go to F</button>
  </>
);

const Page = () => {
  const [[state, Step], setState] = useState([state, DefaultStepComponent]);
  // in Vue.js, you would use: 
  // <component :is="Step" ... />
  const transformState = {
    [DefaultStepComponent]: (state, localState) => { ... },
    ...
  };
  return (
    <Step state={state} setState={setState}  transformState={transformState[Step]} />
  );
};
Enter fullscreen mode Exit fullscreen mode