Interacting with State Machines

State machines are the core of Rive's interactivity. rive-react provides the useStateMachineInput hook to make it easy to find and manipulate state machine inputs directly from your React components.

The useStateMachineInput Hook

This hook is the primary tool for controlling your state machines. It takes the rive instance, the name of the state machine, and the name of the input you want to control.

Finding an Input

Here's how you can get a reference to a boolean input named "isHover" on a state machine named "Button State":

import { useRive, useStateMachineInput } from '@rive-app/react-canvas';

const InteractiveButton = () => {
  const { RiveComponent, rive } = useRive({
    src: 'button.riv',
    stateMachines: 'Button State',
    autoplay: true,
  });

  const isHoverInput = useStateMachineInput(rive, 'Button State', 'isHover');

  const onMouseEnter = () => {
    if (isHoverInput) {
      isHoverInput.value = true;
    }
  };

  const onMouseLeave = () => {
    if (isHoverInput) {
      isHoverInput.value = false;
    }
  };

  return (
    <div onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>
      <RiveComponent />
    </div>
  );
};

Input Types

The useStateMachineInput hook returns an SMIBoolean, SMINumber, or SMITrigger object based on the input type in your Rive file. You can then interact with its value property or fire() method.

  • Boolean (SMIBoolean):

    const isHoverInput = useStateMachineInput(rive, 'sm', 'isHover');
    if (isHoverInput) {
      isHoverInput.value = true;
    }

  • Number (SMINumber):

    const levelInput = useStateMachineInput(rive, 'sm', 'level');
    if (levelInput) {
      levelInput.value = 3;
    }

  • Trigger (SMITrigger): Triggers are actions, so they don't have a value. You call the fire() method on them.

    const playTrigger = useStateMachineInput(rive, 'sm', 'play');
    if (playTrigger) {
      playTrigger.fire();
    }

A Note on Timing

The rive instance is only available after the file has loaded. The useStateMachineInput hook will return null until the rive object is ready and the input is found. It's important to check if the input exists before trying to access its properties, as shown in the examples.

For more advanced state management that decouples your animation logic from your component, consider using the new Data Binding hooks.