Skip to main content
Version: Next

useValue

The useValue() function is a powerful hook designed to manage and animate values within your React components without triggering unnecessary re-renders. It behaves similarly to a ref, holding the current animation state internally.

This hook returns a tuple: [value, setValue].

  • value: The current animated state, which you can directly apply to JSX styles or component props.
  • setValue: A function to update the value, which can trigger a smooth animation when used with motion modifiers.

Basic Usage

The primary use case for useValue() is to animate properties. For instance, to animate an element's width:

import React from 'react';
import { animate, useValue, withSpring, withTiming } from 'react-ui-animate';

export default function App() {
  const [width, setWidth] = useValue(100);

  return (
    <>
      <button onClick={() => setWidth(withSpring(200))}>Animate</button>
      <button onClick={() => setWidth(withTiming(100))}>Reset</button>
      <animate.div
        style={{
          width,
          marginTop: 10,
          height: 100,
          backgroundColor: 'teal',
          borderRadius: 4,
        }}
      />
    </>
  );
}

Immediate vs. Animated Updates

When you assign a raw value (e.g., setWidth(200)), the property changes immediately without animation. To achieve a smooth transition, you must wrap the target value in a animation modifier like (withTiming or withSpring).


Usage

1. Primitive Values (Number & String)

For primitive data types such as numbers or strings, useValue manages a single animated value directly.

Syntax
const [value, setValue] = useValue(initialValue: number | string);
View example
import React from 'react';
import { animate, useValue, withSpring, withTiming } from 'react-ui-animate';

export default function App() {
  const [width, setWidth] = useValue(100);

  return (
    <>
      <button onClick={() => setWidth(withSpring(200))}>Animate</button>
      <button onClick={() => setWidth(withTiming(100))}>Reset</button>
      <animate.div
        style={{
          width,
          marginTop: 10,
          height: 100,
          backgroundColor: 'teal',
          borderRadius: 4,
        }}
      />
    </>
  );
}

2. Array of Primitives

You can also animate an array of values. The hook stores the array and you update it similarly:

Syntax
const [arr, setArr] = useValue(initialArray: number[]);
View example
import React from 'react';
import { useValue, withSpring, animate } from 'react-ui-animate';

export default function App() {
  const [values, setValues] = useValue([0, 0, 0]);

  return (
    <>
      <button onClick={() => setValues(withSpring([10, 100, 200]))}>
        Start
      </button>
      <button onClick={() => setValues([0, 0, 0])}>Reset</button>

      {values.map((value, index) => (
        <animate.div
          key={index}
          style={{
            width: 100,
            height: 100,
            backgroundColor: 'teal',
            left: 0,
            top: 0,
            translateX: value,
            borderRadius: 4,
          }}
        />
      ))}
    </>
  );
}

3. Object of Primitives

You can also initialize useValue with an object whose fields are numbers or strings. The hook returns a matching object

Syntax
const [obj, setObj] = useValue(initialObject: { [key: string]: number | string });
View example
import React from 'react';
import { useValue, withSpring, animate } from 'react-ui-animate';

export default function App() {
  const [obj, setObj] = useValue({ x: 0, y: 0, width: 100, height: 100 });

  return (
    <>
      <button
        onClick={() =>
          setObj(
            withSpring(
              { x: 100, y: 100, width: 200, height: 200 },
              {
                onStart: () => console.log('START'),
                onComplete: () => console.log('Animation complete'),
              }
            )
          )
        }
      >
        Start
      </button>
      <button onClick={() => setObj({ x: 0, y: 0, width: 100, height: 100 })}>
        Reset
      </button>

      <animate.div
        style={{
          width: obj.width,
          height: 100,
          backgroundColor: 'teal',
          left: 0,
          top: 0,
          translateX: obj.x,
          translateY: obj.y,
          borderRadius: 4,
        }}
      />
    </>
  );
}