As XState has released its own React interpreter, this repo has been archived.
A React interpreter for XState that uses renderProps.
yarn add react-xstate-js
or
npm i react-xstate-js -S
import React from 'react';
import { Machine } from 'react-xstate-js';
const myMachineConfig = {
key: 'example1',
initial: 'step1',
states: {
step1: {
on: {
NEXT: 'step2',
},
},
step2: {
on: {
PREVIOUS: 'step1',
NEXT: 'step3',
},
},
step3: {
on: {
PREVIOUS: 'step2',
},
},
},
};
const MyComponent = () => (
<Machine config={myMachineConfig}>
{({ service, state }) => (
<>
<button
type="button"
onClick={() => service.send({ type: 'PREVIOUS' })}
>
previous
</button>
<button
type="button"
onClick={() => service.send({ type: 'NEXT' })}
>
next
</button>
<p>
state:
{' '}
{JSON.stringify(state.value)}
</p>
</>
)}
</Machine>
);
import React from 'react';
import {
MachineConfig, Machine, State, Interpreter
} from 'react-xstate-js'
interface MyStateSchema {
states: {
step1: {}
step2: {}
step3: {}
}
}
type MyEvent = { type: 'NEXT' }
| { type: 'PREVIOUS' }
const myMachineConfig: MachineConfig<{}, MyStateSchema, MyEvent> = {
key: 'example1',
initial: 'step1',
states: {
step1: {
on: {
NEXT: 'step2',
},
},
step2: {
on: {
PREVIOUS: 'step1',
NEXT: 'step3',
},
},
step3: {
on: {
PREVIOUS: 'step2',
},
},
},
}
const MyComponent: React.SFC = () => (
<Machine config={myMachineConfig}>
{({ service, state }: { service: Interpreter<{}, MyStateSchema, MyEvent>, state: State<{}, MyEvent> }) => (
<>
<button
type="button"
onClick={() => service.send({ type: 'PREVIOUS' })}
>
previous
</button>
<button
type="button"
onClick={() => service.send({ type: 'NEXT' })}
>
next
</button>
<p>
state:
{' '}
{JSON.stringify(state.value)}
</p>
</>
)}
</Machine>
)
import React from 'react';
import { Machine } from 'react-xstate-js';
const myMachineConfig = {
key: 'example2',
initial: 'step1',
states: {
step1: {
on: {
NEXT: 'step2',
},
},
step2: {
onEntry: ['myAction'],
on: {
PREVIOUS: 'step1',
NEXT: 'step3',
},
},
step3: {
on: {
PREVIOUS: 'step2',
},
},
},
};
const myMachineOptions = {
actions: {
myAction: () => {
console.log('myAction fired');
},
},
};
const MyComponent = () => (
<Machine
config={myMachineConfig}
options={myMachineOptions}
>
{({ service, state }) => (
<>
<button
type="button"
onClick={() => service.send({ type: 'PREVIOUS' })}
>
previous
</button>
<button
type="button"
onClick={() => service.send({ type: 'NEXT' })}
>
next
</button>
<p>
state:
{' '}
{JSON.stringify(state.value)}
</p>
</>
)}
</Machine>
);
import React from 'react';
import {
MachineConfig, MachineOptions, Machine, State, Interpreter
} from 'react-xstate-js'
interface MyStateSchema {
states: {
step1: {}
step2: {}
step3: {}
}
}
type MyEvent = { type: 'NEXT' }
| { type: 'PREVIOUS' }
const myMachineConfig: MachineConfig<{}, MyStateSchema, MyEvent> = {
key: 'example1',
initial: 'step1',
states: {
step1: {
on: {
NEXT: 'step2',
},
},
step2: {
onEntry: ['myAction'],
on: {
PREVIOUS: 'step1',
NEXT: 'step3',
},
},
step3: {
on: {
PREVIOUS: 'step2',
},
},
},
}
const myMachineOptions: MachineOptions<{}, MyEvent> = {
actions: {
myAction: () => {
console.log('myAction fired');
},
},
};
const MyComponent: React.SFC = () => (
<Machine
config={myMachineConfig}
options={myMachineOptions}
>
{({ service, state }: { service: Interpreter<{}, MyStateSchema, MyEvent>, state: State<{}, MyEvent> }) => (
<>
<button
type="button"
onClick={() => service.send({ type: 'PREVIOUS' })}
>
previous
</button>
<button
type="button"
onClick={() => service.send({ type: 'NEXT' })}
>
next
</button>
<p>
state:
{' '}
{JSON.stringify(state.value)}
</p>
</>
)}
</Machine>
)
import React from 'react';
import {
Machine, assign
} from 'react-xstate-js';
const myMachineConfig = {
key: 'example3',
context: {
foo: '',
},
initial: 'step1',
states: {
step1: {
on: {
NEXT: 'step2',
},
},
step2: {
onEntry: ['myAction'],
on: {
PREVIOUS: 'step1',
NEXT: 'step3',
},
},
step3: {
on: {
PREVIOUS: 'step2',
},
},
},
};
const myMachineOptions = {
actions: {
myAction: assign({ foo: () => 'bar' }),
},
};
const MyComponent = () => (
<Machine
config={myMachineConfig}
options={myMachineOptions}
>
{({ service, state }) => (
<>
<button
type="button"
onClick={() => service.send({ type: 'PREVIOUS' })}
>
previous
</button>
<button
type="button"
onClick={() => service.send({ type: 'NEXT' })}
>
next
</button>
<p>
state:
{' '}
{JSON.stringify(state.value)}
</p>
<p>
context:
{' '}
{JSON.stringify(state.context)}
</p>
</>
)}
</Machine>
);
import React from 'react';
import {
MachineConfig, MachineOptions, Machine, State, Interpreter, assign
} from 'react-xstate-js'
interface MyContext {
foo: string
}
interface MyStateSchema {
states: {
step1: {}
step2: {}
step3: {}
}
}
type MyEvent = { type: 'NEXT' }
| { type: 'PREVIOUS' }
const myMachineConfig: MachineConfig<MyContext, MyStateSchema, MyEvent> = {
key: 'example1',
context: {
foo: '',
},
initial: 'step1',
states: {
step1: {
on: {
NEXT: 'step2',
},
},
step2: {
onEntry: ['myAction'],
on: {
PREVIOUS: 'step1',
NEXT: 'step3',
},
},
step3: {
on: {
PREVIOUS: 'step2',
},
},
},
}
const myMachineOptions: MachineOptions<MyContext, MyEvent> = {
actions: {
myAction: assign({ foo: () => 'bar' }),
},
};
const MyComponent: React.SFC = () => (
<Machine
config={myMachineConfig}
options={myMachineOptions}
>
{({ service, state }: { service: Interpreter<MyContext, MyStateSchema, MyEvent>, state: State<MyContext, MyEvent> }) => (
<>
<button
type="button"
onClick={() => service.send({ type: 'PREVIOUS' })}
>
previous
</button>
<button
type="button"
onClick={() => service.send({ type: 'NEXT' })}
>
next
</button>
<p>
state:
{' '}
{JSON.stringify(state.value)}
</p>
<p>
context:
{' '}
{JSON.stringify(state.context)}
</p>
</>
)}
</Machine>
)
import React from 'react';
import {
Machine,
} from 'react-xstate-js'
const myMachineConfig = {
key: 'example1',
initial: 'step1',
states: {
step1: {
on: {
NEXT: 'step2',
},
},
step2: {
on: {
PREVIOUS: 'step1',
NEXT: 'step3',
},
},
step3: {
on: {
PREVIOUS: 'step2',
},
},
},
}
const mySavedJSONState = `{ "actions": [], "activities": {}, "meta": {}, "events": [], "value": "step3", "event": { "type": "NEXT" }, "historyValue": { "current": "step3", "states": {} }, "history": { "actions": [], "activities": {}, "meta": {}, "events": [], "value": "step2", "event": { "type": "NEXT" }, "historyValue": { "current": "step2", "states": {} }, "history": { "actions": [], "activities": {}, "meta": {}, "events": [], "value": "step1", "event": { "type": "xstate.init" } } } }`
const mySavedState = JSON.parse(mySavedJSONState)
const MyComponent = () => (
<Machine
config={myMachineConfig}
savedState={mySavedState}
>
{({ service, state }) => (
<>
<button
type="button"
onClick={() => service.send({ type: 'PREVIOUS' })}
>
previous
</button>
<button
type="button"
onClick={() => service.send({ type: 'NEXT' })}
>
next
</button>
<p>
state:
{' '}
{JSON.stringify(state.value)}
</p>
</>
)}
</Machine>
)
export default MyComponent
import React from 'react';
import {
MachineConfig, Machine, State, Interpreter
} from 'react-xstate-js'
interface MyStateSchema {
states: {
step1: {}
step2: {}
step3: {}
}
}
type MyEvent = { type: 'NEXT' }
| { type: 'PREVIOUS' }
const myMachineConfig: MachineConfig<{}, MyStateSchema, MyEvent> = {
key: 'example1',
initial: 'step1',
states: {
step1: {
on: {
NEXT: 'step2',
},
},
step2: {
on: {
PREVIOUS: 'step1',
NEXT: 'step3',
},
},
step3: {
on: {
PREVIOUS: 'step2',
},
},
},
}
const mySavedJSONState = `{ "actions": [], "activities": {}, "meta": {}, "events": [], "value": "step3", "event": { "type": "NEXT" }, "historyValue": { "current": "step3", "states": {} }, "history": { "actions": [], "activities": {}, "meta": {}, "events": [], "value": "step2", "event": { "type": "NEXT" }, "historyValue": { "current": "step2", "states": {} }, "history": { "actions": [], "activities": {}, "meta": {}, "events": [], "value": "step1", "event": { "type": "xstate.init" } } } }`
const mySavedState: State<{}, MyEvent> = JSON.parse(mySavedJSONState)
const MyComponent: React.SFC = () => (
<Machine
config={myMachineConfig}
savedState={mySavedState}
>
{({ service, state }: { service: Interpreter<{}, MyStateSchema, MyEvent>, state: State<{}, MyEvent> }) => (
<>
<button
type="button"
onClick={() => service.send({ type: 'PREVIOUS' })}
>
previous
</button>
<button
type="button"
onClick={() => service.send({ type: 'NEXT' })}
>
next
</button>
<p>
state:
{' '}
{JSON.stringify(state.value)}
</p>
</>
)}
</Machine>
)
export default MyComponent
A React interpreter for xstate.
<Machine
config={...}
options={...}
>
{({ service, state }) => (
...
)}
</Machine>
config: xstate machine config.
const myMachineConfig = {
key: 'example1',
initial: 'step1',
states: {
step1: {
on: {
NEXT: 'step2',
},
},
step2: {
on: {
PREVIOUS: 'step1',
NEXT: 'step3',
},
},
step3: {
on: {
PREVIOUS: 'step2',
},
},
},
};
options: xstate machine options.
const myMachineOptions = {
actions: {
myAction: () => {
console.log('myAction fired');
},
},
};
savedState: xstate State.
const mySavedState = {
"actions": [],
"activities": {},
"meta": {},
"events": [],
"value": "step3",
"event": {
"type": "NEXT"
},
"historyValue": {
"current": "step3",
"states": {}
},
"history": {
"actions": [],
"activities": {},
"meta": {},
"events": [],
"value": "step2",
"event": {
"type": "NEXT"
},
"historyValue": {
"current": "step2",
"states": {}
},
"history": {
"actions": [],
"activities": {},
"meta": {},
"events": [],
"value": "step1",
"event": {
"type": "PREVIOUS"
},
"historyValue": {
"current": "step1",
"states": {}
}
}
}
};
const mySavedContext = {
myKeg: 'myValue'
}
service: xstate interpreter.
<Machine {...} >
{({ service }) => (
...
)}
</Machine>
state: xstate state.
<Machine {...} >
{({ state }) => (
...
)}
</Machine>