Actor-based state management & orchestration for complex app logic.
#4863 0696adc21
Thanks @davidkpiano! - Meta objects for state nodes and transitions can now be specified in setup({ types: … })
:
const machine = setup({
types: {
meta: {} as {
layout: string;
}
}
}).createMachine({
initial: 'home',
states: {
home: {
meta: {
layout: 'full'
}
}
}
});
const actor = createActor(machine).start();
actor.getSnapshot().getMeta().home;
// => { layout: 'full' }
// if in "home" state
#4844 5aa6eb05c
Thanks @davidkpiano! - The useSelector(…)
hook from @xstate/react
is now compatible with stores from @xstate/store
.
import { createStore } from '@xstate/store';
import { useSelector } from '@xstate/react';
const store = createStore(
{
count: 0
},
{
inc: {
count: (context) => context.count + 1
}
}
);
function Counter() {
// Note that this `useSelector` is from `@xstate/react`,
// not `@xstate/store/react`
const count = useSelector(store, (state) => state.context.count);
return (
<div>
<button onClick={() => store.send({ type: 'inc' })}>{count}</button>
</div>
);
}
#4844 5aa6eb05c
Thanks @davidkpiano! - The useSelector(…)
hook from @xstate/react
is now compatible with stores from @xstate/store
.
import { createStore } from '@xstate/store';
import { useSelector } from '@xstate/react';
const store = createStore(
{
count: 0
},
{
inc: {
count: (context) => context.count + 1
}
}
);
function Counter() {
// Note that this `useSelector` is from `@xstate/react`,
// not `@xstate/store/react`
const count = useSelector(store, (state) => state.context.count);
return (
<div>
<button onClick={() => store.send({ type: 'inc' })}>{count}</button>
</div>
);
}
#4844 5aa6eb05c
Thanks @davidkpiano! - The useSelector(…)
hook from @xstate/react
is now compatible with stores from @xstate/store
.
import { createStore } from '@xstate/store';
import { useSelector } from '@xstate/react';
const store = createStore(
{
count: 0
},
{
inc: {
count: (context) => context.count + 1
}
}
);
function Counter() {
// Note that this `useSelector` is from `@xstate/react`,
// not `@xstate/store/react`
const count = useSelector(store, (state) => state.context.count);
return (
<div>
<button onClick={() => store.send({ type: 'inc' })}>{count}</button>
</div>
);
}
#4806 f4e0ec48c
Thanks @davidkpiano! - Inline actor logic is now permitted when named actors are present. Defining inline actors will no longer cause a TypeScript error:
const machine = setup({
actors: {
existingActor: fromPromise(async () => {
// ...
})
}
}).createMachine({
invoke: {
src: fromPromise(async () => {
// Inline actor
})
// ...
}
});
#4842 3a57f4c69
Thanks @davidkpiano! - Update README.md
#4839 4a22edb90
Thanks @davidkpiano! - Update JS docs
#4822 f7f1fbbf3
Thanks @davidkpiano! - The clock
and logger
specified in the options
object of createActor(logic, options)
will now propagate to all actors created within the same actor system.
import { setup, log, createActor } from 'xstate';
const childMachine = setup({
// ...
}).createMachine({
// ...
// Uses custom logger from root actor
entry: log('something')
});
const parentMachine = setup({
// ...
}).createMachine({
// ...
invoke: {
src: childMachine
}
});
const actor = createActor(parentMachine, {
logger: (...args) => {
// custom logger for args
}
});
actor.start();
#4752 8a32374e7
Thanks @davidkpiano! - Initial release of @xstate/store
import { createStore } from '@xstate/store';
const store = createStore(
// initial context
{ count: 0, greeting: 'hello' },
// transitions
{
inc: {
count: (context) => context.count + 1
},
updateBoth: {
count: () => 42,
greeting: 'hi'
}
}
);
store.send({
type: 'inc'
});
console.log(store.getSnapshot());
// Logs:
// {
// status: 'active',
// context: {
// count: 1,
// greeting: 'hello'
// }
// }
#4746 b570ba20d
Thanks @davidkpiano! - The new emit(…)
action creator emits events that can be received by listeners. Actors are now event emitters.
import { emit } from 'xstate';
const machine = createMachine({
// ...
on: {
something: {
actions: emit({
type: 'emitted',
some: 'data'
})
}
}
// ...
});
const actor = createActor(machine).start();
actor.on('emitted', (event) => {
console.log(event);
});
actor.send({ type: 'something' });
// logs:
// {
// type: 'emitted',
// some: 'data'
// }
#4777 4abeed9df
Thanks @Andarist! - Added support for params
to enqueueActions