Documentation Index Fetch the complete documentation index at: https://mintlify.com/statelyai/xstate/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The fromActorRef function subscribes to an existing actor and returns a tracked accessor function for its snapshot. It integrates with SolidJS’s reactivity system for fine-grained updates.
function fromActorRef < TActor extends AnyActorRef | undefined >(
actorRef : Accessor < TActor > | TActor
) : Accessor < SnapshotFrom < NonNullable < TActor >> | undefined >
Basic Usage
Subscribe to Actor
With Spawned Actors
Dynamic Actor
import { useActorRef , fromActorRef } from '@xstate/solid' ;
import { createMachine } from 'xstate' ;
const machine = createMachine ({
context: { count: 0 },
// ...
});
export const App = () => {
const actorRef = useActorRef ( machine );
const snapshot = fromActorRef ( actorRef );
return (
< div >
< p > Count: { snapshot ()?. context . count } </ p >
< button onclick = { () => actorRef . send ({ type: 'INCREMENT' }) } >
Increment
</ button >
</ div >
);
};
Reactive Actor Reference
You can pass either a static actor ref or an accessor function:
Static Actor Ref
Accessor Function
import { fromActorRef } from '@xstate/solid' ;
import { createActor } from 'xstate' ;
import { myMachine } from './myMachine' ;
const actorRef = createActor ( myMachine ). start ();
export const App = () => {
// Pass actor ref directly
const snapshot = fromActorRef ( actorRef );
return < div > State: { snapshot ()?. value } </ div > ;
};
Granular Reactivity
The snapshot accessor integrates with SolidJS’s reactivity system:
import { useActor , fromActorRef } from '@xstate/solid' ;
import { createMemo } from 'solid-js' ;
import { myMachine } from './myMachine' ;
export const App = () => {
const [, , actorRef ] = useActor ( myMachine );
const snapshot = fromActorRef ( actorRef );
// These memos only re-compute when their accessed properties change
const count = createMemo (() => snapshot ()?. context . count );
const name = createMemo (() => snapshot ()?. context . name );
const isActive = createMemo (() => snapshot ()?. matches ( 'active' ));
return (
< div >
< p > Count: { count () } </ p >
< p > Name: { name () } </ p >
< p > Active: { isActive () ? 'Yes' : 'No' } </ p >
</ div >
);
};
Undefined Handling
The accessor can return undefined if the actor doesn’t exist:
import { fromActorRef } from '@xstate/solid' ;
import { createSignal , Show } from 'solid-js' ;
import { createActor } from 'xstate' ;
import { myMachine } from './myMachine' ;
export const App = () => {
const [ actorRef , setActorRef ] = createSignal ();
const snapshot = fromActorRef ( actorRef );
const createActor = () => {
setActorRef ( createActor ( myMachine ). start ());
};
return (
< div >
< Show when = { snapshot () } fallback = { < p > No actor </ p > } >
< p > State: { snapshot ()?. value } </ p >
</ Show >
< button onclick = { createActor } > Create Actor </ button >
</ div >
);
};
Selecting Specific Values
Derive specific values from the snapshot:
import { useActor , fromActorRef } from '@xstate/solid' ;
import { createMemo } from 'solid-js' ;
import { largeMachine } from './largeMachine' ;
export const Username = () => {
const [, , actorRef ] = useActor ( largeMachine );
const snapshot = fromActorRef ( actorRef );
// Component only re-renders when username changes
const username = createMemo (() => snapshot ()?. context . user . name );
return < div > Username: { username () } </ div > ;
};
export const Counter = () => {
const [, , actorRef ] = useActor ( largeMachine );
const snapshot = fromActorRef ( actorRef );
// Component only re-renders when count changes
const count = createMemo (() => snapshot ()?. context . count );
return < div > Count: { count () } </ div > ;
};
Multiple Snapshots
Subscribe to multiple actors:
import { useActorRef , fromActorRef } from '@xstate/solid' ;
import { authMachine , dataMachine } from './machines' ;
export const Dashboard = () => {
const authRef = useActorRef ( authMachine );
const dataRef = useActorRef ( dataMachine );
const authSnapshot = fromActorRef ( authRef );
const dataSnapshot = fromActorRef ( dataRef );
return (
< div >
< p > Auth: { authSnapshot ()?. value } </ p >
< p > Data: { dataSnapshot ()?. value } </ p >
</ div >
);
};
With Effects
Use createEffect to react to snapshot changes:
import { useActor , fromActorRef } from '@xstate/solid' ;
import { createEffect } from 'solid-js' ;
import { myMachine } from './myMachine' ;
export const App = () => {
const [, , actorRef ] = useActor ( myMachine );
const snapshot = fromActorRef ( actorRef );
// Effect runs when snapshot changes
createEffect (() => {
const current = snapshot ();
if ( current ?. matches ( 'success' )) {
console . log ( 'Success!' , current . context );
}
});
return < div > { /* ... */ } </ div > ;
};
Comparison with useActor
useActor
fromActorRef + useActorRef
import { useActor } from '@xstate/solid' ;
import { myMachine } from './myMachine' ;
export const App = () => {
// Creates actor, returns [snapshot, send, actorRef]
const [ snapshot , send ] = useActor ( myMachine );
return (
< div >
< p > State: { snapshot . value } </ p >
< button onclick = { () => send ({ type: 'NEXT' }) } >
Next
</ button >
</ div >
);
};
Use useActor when you need the full tuple. Use fromActorRef when:
You already have an actor ref
You’re working with spawned/child actors
You need more control over subscriptions
TypeScript
The function is fully typed:
import { setup } from 'xstate' ;
import { useActor , fromActorRef } from '@xstate/solid' ;
import type { Accessor } from 'solid-js' ;
interface User {
id : string ;
name : string ;
}
const machine = setup ({
types: {
context: {} as {
user : User ;
count : number ;
}
}
}). createMachine ({
context: {
user: { id: '1' , name: 'Alice' },
count: 0
}
});
export const App = () => {
const [, , actorRef ] = useActor ( machine );
const snapshot = fromActorRef ( actorRef );
// TypeScript infers the snapshot type
const userName : Accessor < string | undefined > = () => {
return snapshot ()?. context . user . name ;
};
return < div > User : { userName ()} </ div > ;
};
Implementation Details
The fromActorRef function:
Creates a memo to track the actor ref (if passed as accessor)
Uses createImmutable to create a tracked snapshot store
Uses createEffect to subscribe to actor changes
Updates the store with new snapshots
Handles actor switching by resubscribing
Automatically unsubscribes on cleanup via onCleanup
Returns an accessor function for the current snapshot
useActor Create and manage actors with tracked snapshots
Solid Integration Back to Solid integration overview