Skip to main content
This example shows how to use context to store and update data in a state machine.

Overview

The counter machine demonstrates:
  • Using context to store a count value
  • Using assign actions to update context
  • Handling multiple event types
  • Stateless machines (no explicit states)

Machine Definition

import { assign, createMachine } from 'xstate';

export const counterMachine = createMachine({
  id: 'counter',
  context: {
    count: 0
  },
  on: {
    increment: {
      actions: assign({
        count: ({ context }) => context.count + 1
      })
    },
    decrement: {
      actions: assign({
        count: ({ context }) => context.count - 1
      })
    }
  }
});

Implementation

1
Define context
2
Set the initial context with a count property:
3
context: {
  count: 0
}
4
Create assign actions
5
Use assign() to update context values:
6
increment: {
  actions: assign({
    count: ({ context }) => context.count + 1
  })
}
7
Access context in snapshots
8
Read context from the state snapshot:
9
counterActor.subscribe((state) => {
  render(state.context.count);
});
10
Send events to update
11
Trigger context updates by sending events:
12
incrementButton.addEventListener('click', () => {
  counterActor.send({ type: 'increment' });
});

Complete Example

import './style.css';
import { counterMachine } from './counterMachine';
import { createActor } from 'xstate';

const incrementButton = document.querySelector<HTMLButtonElement>('#increment')!;
const decrementButton = document.querySelector<HTMLButtonElement>('#decrement')!;
const outputEl = document.querySelector<HTMLDivElement>('#output')!;

function render(count: number): void {
  outputEl.innerHTML = `Count is ${count}`;
}

const counterActor = createActor(counterMachine);

counterActor.subscribe((state) => {
  render(state.context.count);
});

counterActor.start();

incrementButton?.addEventListener('click', () => {
  counterActor.send({ type: 'increment' });
});

decrementButton?.addEventListener('click', () => {
  counterActor.send({ type: 'decrement' });
});

Key Concepts

  • Context: Stores extended state data (the count value)
  • assign(): Action creator for updating context
  • Stateless machines: Machines without explicit states can still respond to events
  • Immutability: Context updates create new objects, preserving immutability

When to Use Context

Use context for:
  • Numeric values (counters, timers)
  • Form data
  • API responses
  • User information
  • Any data that changes over time