Function useSyncedMachine

  • Uses a synced state machine with the constructor.

    This hook can transition the state of the state machine without re-rendering.

    The state machine constructor is executed only once per hook. It is idempotent unless it depends on external mutable values within the constructor.

    In most cases, useSyncedMachine used in conjunction with props. It is intended to serve as a filter to determine whether multiple event sources, including the DOM, have triggered a state transition.

    Type Parameters

    • D

      The type of state machine definition.

    Parameters

    Returns [getState: (() => State<D>), send: Send<D>]

    An array with two elements:

    • The first element is a function that returns the current state of the state machine.
    • The second element is a function that sends an event to the state machine.
    import { useSyncedMachine, createMachine } from "use-machine-ts"

    function machine() {
    return createMachine({
    // definition
    {
    initial: "inactive",
    states: {
    inactive: {
    on: { TOGGLE: "active" },
    effect: "onInactive",
    },
    active: {
    on: { TOGGLE: "inactive" },
    effect: "onActive",
    },
    },
    },
    // configuration
    {
    effects: {
    onActive: () => {
    console.log("Just activated!")
    },
    onInactive: () => {
    console.log("Just deactivated!")
    },
    },
    },
    })
    }

    function ToggleButton(props: {}) {
    const [getState, send] = useSyncedMachine(machine)

    return (
    <button onClick={() => send("TOGGLE")} type="button">
    Toggle
    </button>
    )
    }
  • Uses a synced state machine with the constructor and props.

    This hook can transition the state of the state machine without re-rendering.

    The state machine constructor is executed only once per hook. It is idempotent unless it depends on external mutable values within the constructor.

    The props passed to the state machine constructor are different from the props of a React component; they are represented as a function. When this function is executed, it returns a reference to the props passed to the hook. This mechanism is implemented using React.useRef, ensuring that it always returns a reference to the latest props.

    It is intended to serve as a filter to determine whether multiple event sources, including the DOM, have triggered a state transition.

    Type Parameters

    • D

      The type of state machine definition.

    • P

      The type of props for the state machine factory.

    Parameters

    • machine: ((props: (() => P)) => Machine<D>)

      The state machine factory.

    • props: P

      The props for the state machine factory.

    Returns [getState: (() => State<D>), send: Send<D>]

    An array with two elements:

    • The first element is a function that returns the current state of the state machine.
    • The second element is a function that sends an event to the state machine.
    import { useSyncedMachine, createMachine } from "use-machine-ts"

    function machine(props: () => { onToggle }) {
    return createMachine({
    // definition
    {
    initial: "inactive",
    states: {
    inactive: {
    on: { TOGGLE: "active" },
    effect: "onInactive",
    },
    active: {
    on: { TOGGLE: "inactive" },
    effect: "onActive",
    },
    },
    },
    // configuration
    {
    effects: {
    onActive: () => {
    const { onToggle } = props()
    onToggle("active")
    },
    onInactive: () => {
    const { onToggle } = props()
    onToggle("inactive")
    },
    },
    },
    })
    }

    function ToggleButton(props: { onToggle: (value: "active" | "inactive") => void }) {
    const [, send] = useSyncedMachine(machine, props)

    return (
    <button onClick={() => send("TOGGLE")} type="button">
    Toggle
    </button>
    )
    }
  • Uses a synced state machine with the pre-created instance.

    This hook can transition the state of the state machine without re-rendering.

    We can use a pre-created state machine instance with the hook. It is idempotent unless it depends on external mutable values within the effect. In most cases, it is better to define the state machine using the constructor instead.

    To enable tree shaking, you can indicate to the bundler that this function has no side effects by using the @__PURE__ or #__PURE__ annotation as needed.

    In most cases, useSyncedMachine used in conjunction with props. It is intended to serve as a filter to determine whether multiple event sources, including the DOM, have triggered a state transition.

    Type Parameters

    • D

      The type of state machine definition.

    Parameters

    Returns [getState: (() => State<D>), send: Send<D>]

    An array with two elements:

    • The first element is a function that returns the current state of the state machine.
    • The second element is a function that sends an event to the state machine.
    import { useSyncedMachine, createMachine } from "use-machine-ts"

    const machine = createMachine({
    // definition
    {
    initial: "inactive",
    states: {
    inactive: {
    on: { TOGGLE: "active" },
    effect: "onInactive",
    },
    active: {
    on: { TOGGLE: "inactive" },
    effect: "onActive",
    },
    },
    },
    // configuration
    {
    effects: {
    onActive: () => {
    console.log("Just activated!")
    },
    onInactive: () => {
    console.log("Just deactivated!")
    },
    },
    },
    })

    function ToggleButton(props: {}) {
    const [getState, send] = useSyncedMachine(machine)

    return (
    <button onClick={() => send("TOGGLE")} type="button">
    Toggle
    </button>
    )
    }
  • Define a synced state machine and uses it.

    This hook can transition the state of the state machine without re-rendering.

    This approach is useful when you want to quickly define and use a simple state machine on the spot. For complex definitions, it is usually better to write them in a separate file and import it. However, if the definition does not impair readability, keeping it within the component can actually make it more readable.

    In most cases, useSyncedMachine used in conjunction with props. It is intended to serve as a filter to determine whether multiple event sources, including the DOM, have triggered a state transition.

    Type Parameters

    • D extends {
          $schema?: Schema<D, ["$schema"], "$schema" extends keyof D
              ? D[keyof D & "$schema"] extends undefined
                  ? undefined
                  : D[keyof D & "$schema"]
              : undefined, "strict" extends keyof ("$schema" extends keyof D
                  ? D[keyof (...) & "$schema"] extends undefined
                      ? undefined
                      : D[keyof (...) & "$schema"]
                  : undefined)
              ? ("$schema" extends keyof D
                      ? D[(...) & (...)] extends undefined
                          ? undefined
                          : D[(...) & (...)]
                      : undefined)[keyof ("$schema" extends keyof (...)
                      ? (...) extends (...)
                          ? (...)
                          : (...)
                      : undefined) & "strict"] extends undefined
                  ? undefined
                  : ("$schema" extends keyof D
                      ? D[(...) & (...)] extends undefined
                          ? undefined
                          : D[(...) & (...)]
                      : undefined)[keyof ("$schema" extends keyof (...)
                      ? (...) extends (...)
                          ? (...)
                          : (...)
                      : undefined) & "strict"]
              : undefined, "events" extends keyof ("$schema" extends keyof D
                  ? D[keyof (...) & "$schema"] extends undefined
                      ? undefined
                      : D[keyof (...) & "$schema"]
                  : undefined)
              ? ("$schema" extends keyof D
                      ? D[(...) & (...)] extends undefined
                          ? undefined
                          : D[(...) & (...)]
                      : undefined)[keyof ("$schema" extends keyof (...)
                      ? (...) extends (...)
                          ? (...)
                          : (...)
                      : undefined) & "events"] extends undefined
                  ? undefined
                  : ("$schema" extends keyof D
                      ? D[(...) & (...)] extends undefined
                          ? undefined
                          : D[(...) & (...)]
                      : undefined)[keyof ("$schema" extends keyof (...)
                      ? (...) extends (...)
                          ? (...)
                          : (...)
                      : undefined) & "events"]
              : undefined, "context" extends keyof ("$schema" extends keyof D
                  ? D[keyof (...) & "$schema"] extends undefined
                      ? undefined
                      : D[keyof (...) & "$schema"]
                  : undefined)
              ? ("$schema" extends keyof D
                      ? D[(...) & (...)] extends undefined
                          ? undefined
                          : D[(...) & (...)]
                      : undefined)[keyof ("$schema" extends keyof (...)
                      ? (...) extends (...)
                          ? (...)
                          : (...)
                      : undefined) & "context"] extends undefined
                  ? undefined
                  : ("$schema" extends keyof D
                      ? D[(...) & (...)] extends undefined
                          ? undefined
                          : D[(...) & (...)]
                      : undefined)[keyof ("$schema" extends keyof (...)
                      ? (...) extends (...)
                          ? (...)
                          : (...)
                      : undefined) & "context"]
              : undefined>;
          initial: IsPlainObject<"states" extends keyof D
                  ? D[keyof D & "states"] extends undefined
                      ? undefined
                      : D[keyof D & "states"]
                  : undefined> extends false
              ? "Error: States must be a plain object."
              : [keyof ("states" extends keyof D
                      ? D[keyof (...) & "states"] extends undefined
                          ? undefined
                          : D[keyof (...) & "states"]
                      : undefined)] extends [never]
                  ? "Error: No states defined."
                  : IsStringLiteral<keyof ("states" extends keyof D
                          ? D[(...) & (...)] extends undefined
                              ? undefined
                              : D[(...) & (...)]
                          : undefined)> extends false
                      ? "Error: States have no literal string value."
                      : keyof ("states" extends keyof D
                          ? D[keyof (...) & "states"] extends undefined
                              ? undefined
                              : D[keyof (...) & "states"]
                          : undefined);
          on?: On<D, ["on"], never>;
          states: IsPlainObject<"states" extends keyof D
                  ? D[keyof D & "states"] extends undefined
                      ? undefined
                      : D[keyof D & "states"]
                  : undefined> extends false
              ? "Error: States must be a plain object."
              : [keyof ("states" extends keyof D
                      ? D[keyof (...) & "states"] extends undefined
                          ? undefined
                          : D[keyof (...) & "states"]
                      : undefined)] extends [never]
                  ? {
                      [NEVER]?: undefined;
                  }
                  : IsStringLiteral<keyof ("states" extends keyof D
                          ? D[(...) & (...)] extends undefined
                              ? undefined
                              : D[(...) & (...)]
                          : undefined)> extends false
                      ? "Error: State values must be literal strings."
                      : {
                          readonly [V in string | number | symbol]: V extends ReservedKeyword
                              ? `Error: State value '${V<V>}' is reserved.`
                              : Definition.State<D, ["states", V], never, never>
                      };
      } & ({
          context: Context<D>;
      } | {
          context?: Context<D>;
      })

      The type of state machine definition.

    Parameters

    Returns [getState: (() => State<D>), send: Send<D>]

    An array with two elements:

    • The first element is a function that returns the current state of the state machine.
    • The second element is a function that sends an event to the state machine.
    import { useSyncedMachine } from "use-machine-ts"

    function ToggleButton(props: {}) {
    const [getState, send] = useSyncedMachine(
    // definition
    {
    initial: "inactive",
    states: {
    inactive: {
    on: { TOGGLE: "active" },
    },
    active: {
    on: { TOGGLE: "inactive" },
    },
    },
    },
    )

    return (
    <button onClick={() => send("TOGGLE")} type="button">
    Toggle
    </button>
    )
    }
  • Define a synced state machine and uses it.

    This hook can transition the state of the state machine without re-rendering.

    This approach is useful when you want to quickly define and use a simple state machine on the spot. For complex definitions, it is usually better to write them in a separate file and import it. However, if the definition does not impair readability, keeping it within the component can actually make it more readable.

    In most cases, useSyncedMachine used in conjunction with props. It is intended to serve as a filter to determine whether multiple event sources, including the DOM, have triggered a state transition.

    Type Parameters

    • D extends {
          $schema?: Schema<D, ["$schema"], "$schema" extends keyof D
              ? D[keyof D & "$schema"] extends undefined
                  ? undefined
                  : D[keyof D & "$schema"]
              : undefined, "strict" extends keyof ("$schema" extends keyof D
                  ? D[keyof (...) & "$schema"] extends undefined
                      ? undefined
                      : D[keyof (...) & "$schema"]
                  : undefined)
              ? ("$schema" extends keyof D
                      ? D[(...) & (...)] extends undefined
                          ? undefined
                          : D[(...) & (...)]
                      : undefined)[keyof ("$schema" extends keyof (...)
                      ? (...) extends (...)
                          ? (...)
                          : (...)
                      : undefined) & "strict"] extends undefined
                  ? undefined
                  : ("$schema" extends keyof D
                      ? D[(...) & (...)] extends undefined
                          ? undefined
                          : D[(...) & (...)]
                      : undefined)[keyof ("$schema" extends keyof (...)
                      ? (...) extends (...)
                          ? (...)
                          : (...)
                      : undefined) & "strict"]
              : undefined, "events" extends keyof ("$schema" extends keyof D
                  ? D[keyof (...) & "$schema"] extends undefined
                      ? undefined
                      : D[keyof (...) & "$schema"]
                  : undefined)
              ? ("$schema" extends keyof D
                      ? D[(...) & (...)] extends undefined
                          ? undefined
                          : D[(...) & (...)]
                      : undefined)[keyof ("$schema" extends keyof (...)
                      ? (...) extends (...)
                          ? (...)
                          : (...)
                      : undefined) & "events"] extends undefined
                  ? undefined
                  : ("$schema" extends keyof D
                      ? D[(...) & (...)] extends undefined
                          ? undefined
                          : D[(...) & (...)]
                      : undefined)[keyof ("$schema" extends keyof (...)
                      ? (...) extends (...)
                          ? (...)
                          : (...)
                      : undefined) & "events"]
              : undefined, "context" extends keyof ("$schema" extends keyof D
                  ? D[keyof (...) & "$schema"] extends undefined
                      ? undefined
                      : D[keyof (...) & "$schema"]
                  : undefined)
              ? ("$schema" extends keyof D
                      ? D[(...) & (...)] extends undefined
                          ? undefined
                          : D[(...) & (...)]
                      : undefined)[keyof ("$schema" extends keyof (...)
                      ? (...) extends (...)
                          ? (...)
                          : (...)
                      : undefined) & "context"] extends undefined
                  ? undefined
                  : ("$schema" extends keyof D
                      ? D[(...) & (...)] extends undefined
                          ? undefined
                          : D[(...) & (...)]
                      : undefined)[keyof ("$schema" extends keyof (...)
                      ? (...) extends (...)
                          ? (...)
                          : (...)
                      : undefined) & "context"]
              : undefined>;
          initial: IsPlainObject<"states" extends keyof D
                  ? D[keyof D & "states"] extends undefined
                      ? undefined
                      : D[keyof D & "states"]
                  : undefined> extends false
              ? "Error: States must be a plain object."
              : [keyof ("states" extends keyof D
                      ? D[keyof (...) & "states"] extends undefined
                          ? undefined
                          : D[keyof (...) & "states"]
                      : undefined)] extends [never]
                  ? "Error: No states defined."
                  : IsStringLiteral<keyof ("states" extends keyof D
                          ? D[(...) & (...)] extends undefined
                              ? undefined
                              : D[(...) & (...)]
                          : undefined)> extends false
                      ? "Error: States have no literal string value."
                      : keyof ("states" extends keyof D
                          ? D[keyof (...) & "states"] extends undefined
                              ? undefined
                              : D[keyof (...) & "states"]
                          : undefined);
          on?: On<D, ["on"], G>;
          states: IsPlainObject<"states" extends keyof D
                  ? D[keyof D & "states"] extends undefined
                      ? undefined
                      : D[keyof D & "states"]
                  : undefined> extends false
              ? "Error: States must be a plain object."
              : [keyof ("states" extends keyof D
                      ? D[keyof (...) & "states"] extends undefined
                          ? undefined
                          : D[keyof (...) & "states"]
                      : undefined)] extends [never]
                  ? {
                      [NEVER]?: undefined;
                  }
                  : IsStringLiteral<keyof ("states" extends keyof D
                          ? D[(...) & (...)] extends undefined
                              ? undefined
                              : D[(...) & (...)]
                          : undefined)> extends false
                      ? "Error: State values must be literal strings."
                      : {
                          readonly [V in string | number | symbol]: V extends ReservedKeyword
                              ? `Error: State value '${V<V>}' is reserved.`
                              : Definition.State<D, ["states", V], G, E>
                      };
      } & ({
          context: Context<D>;
      } | {
          context?: Context<D>;
      })

      The type of state machine definition.

    • const G extends string

      The type of guards for state machine functions.

    • const E extends string

      The type of effects for state machine functions.

    Parameters

    Returns [getState: (() => State<D>), send: Send<D>]

    An array with two elements:

    • The first element is a function that returns the current state of the state machine.
    • The second element is a function that sends an event to the state machine.