React
useAniStates
A reactive hook for managing and transitioning between multiple animation states.
This hook is a React-specific wrapper around the core createStates function. It's designed for components with multiple, distinct visual states (e.g., idle, hover, active) and provides a simple, reactive API to manage transitions between them.
Example
import { a } from "@freestylejs/ani-core";
import { useAniRef, useAniStates } from "@freestylejs/ani-react";
import { useMemo, useRef } from "react";
const StateButton = () => {
const ref = useRef<HTMLButtonElement>(null)
// 1. Define the animations for each state.
// Memoize this object to prevent re-creating the state machine on every render.
const animations = useMemo(
() => ({
idle: a.ani({
to: { scale: 1, opacity: 0.7 },
duration: 0.5,
timing: a.timing.linear(),
}),
hover: a.ani({
to: { scale: 1.25, opacity: 1 },
duration: 1.5,
timing: a.timing.linear(),
}),
}),
[]
)
// 2. Use the hook to create the state machine.
// It returns the current state info and a function to transition.
const [{ timeline }, transitionTo] = useAniStates({
initial: 'idle',
initialFrom: {
opacity: 0,
scale: 1,
},
states: animations,
})
// 3. Connect the active timeline to the DOM element for high-performance updates.
useAniRef(ref, { timeline })
return (
<button
ref={ref}
onMouseEnter={() => transitionTo('hover')}
onMouseLeave={() => transitionTo('idle')}
className="rounded-md scale-100 opacity-100 bg-blue-500 px-4 py-2 transition-all"
>
Hover Me
</button>
)
}Usage & Concepts
Overview
The useAniStates hook simplifies stateful animation logic in React. It manages the active animation state and its corresponding timeline, automatically handling seamless transitions between states. When you call transitionTo, it uses the current animation's value as the starting point for the next animation, ensuring smooth, interruptible effects.
When to Use
- Do use
useAniStatesfor components with a finite number of visual states, such as buttons, interactive cards, or navigation items. - Do combine
useAniStateswithuseAniReffor high-performance style animations that react to state changes without causing re-renders. - Don't create the
statesobject inside the render function without memoization, as this will create a new state machine on every render and lead to unexpected behavior.
API Reference
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
props | StateProps<AnimationStates> | The configuration object for the state machine. | — |
Return Value
The hook returns a readonly tuple with the following structure:
| Index | Type | Description |
|---|---|---|
[0] | object | An object containing the current state name and the active timeline instance. |
[1] | function | The transitionTo function to switch between animation states. |
Type Definitions
import { AnimationStateShape, StateProps, GetTimeline, StateController } from '@freestylejs/ani-core';
declare function useAniStates<const AnimationStates extends AnimationStateShape>(
props: StateProps<AnimationStates>
): readonly [
{
state: keyof AnimationStates;
timeline: GetTimeline<AnimationStates>;
},
StateController<AnimationStates>['transitionTo']
];Related Components
createStates- The core function that this hook is built upon.useAniRef- To apply the stateful animations to the DOM without re-renders.useAni- To reactively read the animation values from the active timeline.