react-spring

repository·next·Indexed 12 days ago

https://github.com/pmndrs/react-spring

A cross-platform, spring-physics first animation engine for React. It provides declarative and imperative tools for fluid animations in web (react-dom) and 3D (react-three-fiber) environments via @react-spring/web and @react-spring/three. Includes specialized packages such as @react-spring/parallax for scrollable parallax effects and @react-spring/rafz for coordinating requestAnimationFrame calls.

Tokens
57.9K
Snippets
173
Records
259
Agent score
98%

What's inside react-spring

  1. Use @react-spring/rafz to coordinate requestAnimationFrame

    next
    @react-spring/rafz is a lightweight utility (< 700 bytes min+gzip) designed to coordinate requestAnimationFrame calls across your application or libraries. It provides features like timeout support, batching support (e.g., ReactDOM.unstable_batchedUpdates), error isolation, and continuous execution to reduce frame skips.
  2. What is a target in react-spring?

    next

    In react-spring, a target is a react reconciler (also known as a react renderer). It is a custom renderer responsible for creating, updating, and removing elements within a specific environment.

    While react-spring can be used for server-side rendering, the term 'target' specifically refers to the platform-specific reconciler being used. The two primary built-in targets are:

    • web: Uses react-dom to handle DOM elements.
    • three: Uses react-three-fiber to handle Three.js elements.

    When you use a target, you get access to a set of animated components (like animated.div for web) that are optimized for that specific reconciler.

  3. Use the SpringRef imperative API

    next

    The SpringRef is React Spring's imperative API, allowing you to control animations outside of the standard declarative React render cycle.

    For functional components, the recommended way to initialize it is via the useSpringRef hook. You then pass this ref to a useSpring call to link the imperative controller to the spring animation.

    For class components or environments where hooks are unavailable, you can initialize it by calling the SpringRef() function directly.

    import { animated, useSpring, useSpringRef } from '@react-spring/web'
    
    function MyComponent() {
      const api = useSpringRef()
    
      const props = useSpring({
        ref: api,
        from: { opacity: 0 },
        to: { opacity: 1 },
      })
    
      return <animated.div style={props}>Hello World</animated.div>
    }
  4. Map Route files to URLs in React Router 7

    next

    The migration uses @react-router/fs-routes to preserve existing Remix v2 flat-route file naming, ensuring URLs remain byte-identical.

    Key Route Mappings:

    • _index.tsx $\rightarrow$ / (Landing page)
    • $.tsx $\rightarrow$ (Catch-all 404) Splat route
    • docs.tsx $\rightarrow$ /docs (Pathless layout for children)
    • docs._index.mdx $\rightarrow$ /docs (Docs landing)
    • docs.getting-started.mdx $\rightarrow$ /docs/getting-started
    • examples.tsx $\rightarrow$ /examples

    Route Invariants:

    • All migrated routes (except the 404 splat) must return HTTP 200.
    • The flatRoutes() configuration must ignore dotfiles and CSS modules (e.g., ignoredRouteFiles: ['**/.*', '**/*.css']) to prevent them from being treated as routes.
  5. Choose between Hooks and Components in React Spring

    next

    React Spring provides both Hook-based and Component-based APIs for its animations.

    • Hooks (Recommended): The library recommends using the hook version (e.g., useSpring) as it aligns better with modern React patterns.
    • Components: The component version (e.g., <Spring />) is provided primarily for compatibility with older codebases or class components. It acts as a light wrapper around the hook logic and uses a render props pattern to expose the animated styles.
  6. How Fluids enable event-driven animations

    next

    Fluids is a lightweight glue layer used throughout react-spring to implement an observable, event-driven system.

    It allows parent nodes to send events to child nodes. For example, when a FluidObserver observes an event, it can trigger an action in its child. In the context of SpringValue, an event can trigger the _start function, which initiates the animation of the value and subsequently updates the attached animated DOM node.

  7. How to use event listeners with react-spring

    next

    React Spring provides several event hooks to react to the state of an animation. You can attach these events to a spring in two ways:

    1. Global Event: Provide a single function to the event key. This function triggers when the event occurs for the entire spring.
    2. Key-specific Events: Provide an object where the keys match the spring's property keys. This allows you to run different logic for different animating properties (e.g., reacting to x differently than y).

    Note that onStart is called after the first animation tick, so the values at that moment are considered 'dirty'.

    // Global event: triggers once for the whole spring
    useSpring(
      () => ({
        x: 0,
        y: 0,
        onStart: () => console.log('the spring has started'),
      }),
      []
    )
    
    // Key-specific events: triggers for each specific key
    useSpring(
      () => ({
        x: 0,
        y: 0,
        onStart: {
          x: () => console.log('x key has started'),
          y: () => console.log('y key has started'),
        },
      }),
      []
    )
  8. Preserve Remix v2 Flat Routes in React Router 7

    next

    React Router 7 framework mode typically requires explicit route configuration. To preserve the Remix v2 flat-file naming convention (e.g., docs.components.use-spring.mdx resolving to /docs/components/use-spring) without renaming files, use @react-router/fs-routes in your app/routes.ts file.

    // docs/app/routes.ts
    import { flatRoutes } from '@react-router/fs-routes'
    import { type RouteConfig } from '@react-router/dev/routes'
    
    export default flatRoutes() satisfies RouteConfig
  9. How the useTransition render function works

    next

    The transitions object returned by useTransition is a function that accepts a render function. This render function is used to map your data items to animated components.

    The render function signature is: render(style, item, transitionState, index) => ReactNode

    • style: An object containing the current spring values (e.g., opacity, transform). The values in this object correspond to the state of the animation (e.g., if the item is ENTERING, it uses the keys from the enter property of your config).
    • item: The actual data item from your array (e.g., if your array is [1, 2, 3], the item will be a number).
    • transitionState: Information about the current state of the transition for that item.
    • index: The index of the item in the array.
    transitions((style, item, transitionState, index) => (
      <animated.div style={style}>
        {item}
      </animated.div>
    ))
  10. Understand the Vitest migration changes

    next

    The testing infrastructure has moved from Jest + Cypress to Vitest + Playwright (Chromium).

    Key changes:

    • jest.config.js is now vitest.config.ts.
    • The jsdom environment has been replaced by Chromium via Playwright.
    • E2E tests now use Vite served programmatically with a Vitest E2E project instead of start-server-and-test + Cypress.

    What remains the same:

    • Animation testing helpers (advance, advanceByTime, advanceUntil, advanceUntilIdle, advanceUntilValue, getFrames, countBounces, setSkipAnimation) are unchanged and do not require rewriting.
    • packages/core/test/setup.ts uses the same helpers, though they now provide Vitest globals instead of Jest globals.