
State Modeling in React with XState
Learning Paths:
Topics:
Table of Contents
Introduction
State Machines
Component State in React
David describes software modeling as knowing how an application will behave at any given time. A React component can model its state with the useState hook, however, the logic can get complex when there are multiple state values to manage.Diagramming a State Machine
David uses an online tool Excalidraw to diagram the state machine for the toggle component. There are three states: inactive, pending, and active. The events that trigger the stage changes are the toggle event and a success event.Refactoring with useReducer
David recommends refactoring any useState hooks to the useReducer hook as a first step for incorporating a state machine. The state logic is centralized within the reducer making it easier to understand and share across components.Using a Machine Object
David refactors the switch statement to use a machine object. The flow of the component's state changes are configured in the machine object and can be visualized with an tool like the XState Visualizer.State Machine Exercise
Students are instructed to create a state machine from scratch using the useReducer hook.State Machine Solution
David live codes the solution to the State Machine exercise.
XState Machines
Refactoring to XState useMachine
David describes XState as a state machine and state chart library. The state machine object is used within XState by passing it to the createMachine method.Using XState Exercise
Students are instructed to use the state machine within XState and XState React.Using XState Solution
David live codes the solution to the Using XState exercise. The XState Inspect tool is also covered in this segment.Extended State
David explains that extended state properties are state properties without finite values. They are stored in a context object within the state machine.Context Exercise
Students are instructed to use context property to hold the extended state and the assign method to update context property in an action.Context Solution
David live codes the solution to the Context exercise.Parameterizing Actions
David demonstrates how actions can be parameterized for more reusability. Custom parameters are passed to the useMachine hook which overrides the default parameters in the machine.Parameterizing Actions Exercise
Students are instructed to move the actions created with the assign() method to parameterized actions.Parameterizing Actions Solution
David live codes the solution to the Parameterizing Actions exercise.Integrating 3rd Party Libraries
David demonstrates how to use XState events with 3rd party libraries in React.
Transitions
Guarded Transitions
David explains how guarded transitions prevent state transitions if a condition is not met. The condition is a function which returns a boolean indicating if the transition should run.Guarded Transitions Exercise
Students are instructed to use guarded transitions to model what happens when the timer expires.Guarded Transitions Solution
David live codes the solution to the Guarded Transitions exercise.Eventless Transitions
David explains that eventless transitions are always taken when the state machine is first entered. They are defined using the "always" property of the state node and contain a conditional guard which must evaluate to true in order to run.Eventless Transitions Exercise
Students are instructed to use eventless transitions to detect when the timer expires and simplify the guard logic.Eventless Transitions Solution
David live codes the solution to the Eventless Transitions exercise.
State Types
Shared States with useService
David uses the useService hook to subscribe to changes in the local time service. The updated time will then be sent to the ForeignClock component's state machine to keep it up-to-date with the Clock component.Hierarchical States
David explains that hierarchical states are states nested inside a parent state. This creates a composite state where events can propagate from the sub-state and be handled in the parent state.Hierarchical States Exercise
Students are instructed to use hierarchical states to add overtime logic, and use forbidden transitions to adjust the behavior of the nested states.Hierarchical States Solution
David live codes the solution to the Hierarchical States exercise. This segment also demonstrates how to use final states to transition a parent state.
Actors
Invoking Actors
David invokes a promise and a callback to demonstrate how to communicate between actors within a state machine. Promises use onDone and onError transitions based on their result. Callbacks return data after their execution.Invoking Actors Exercise
Students are instructed to move the interval logic from the useEffect hook directly into the state machine.Invoking Actors Solution
David live codes the solution to the Invoking Actors exercise.Spawning Actors
David refactors the alarm functionality into a separate component or actor, and creates a state machine for the parent application. After an alarm actor is spawned, its local state is private unless the state is shared with another actor or the parent application by sending an event.Spawning Actors Exercise
Students are instructed to distribute the state with actors.Spawning Actors Solution
David live codes the solution to the Spawning Actors exercise.Model-Based Testing
David adds model-based testing to the timer application. This approach describes the behavior of the application as a state machine allowing the tests to be written based on how the user will interact with the application.