GSAP React Integration (@gsap/react)

repository·main·Indexed 43 days ago

https://github.com/greensock/react

Specialized React integration for GSAP version 2.1.2 featuring the useGSAP() hook. It provides a drop-in replacement for useEffect() and useLayoutEffect() with automatic cleanup, SSR compatibility, and scoping via GSAP context. Includes contextSafe() for managing event handlers and callbacks to ensure proper animation cleanup upon component unmounting.

Tokens
2.2K
Snippets
8
Records
8
Agent score
6%

What's inside GSAP

  1. Ensure callbacks are context-safe with contextSafe()

    main

    Functions executed after the initial useGSAP() call (like click handlers, setTimeout, or event listeners) are not automatically tracked by the GSAP context. To ensure animations created inside these functions are properly scoped and automatically cleaned up when the component unmounts, you must wrap them in contextSafe().

    You can access contextSafe in two ways:

    1. From the returned object: When calling useGSAP with a config object.
    2. As a second argument: Inside the useGSAP() callback function.

    Note: If you add event listeners manually inside useGSAP, remember to remove them in the cleanup function returned by the hook.

    // Method 1: Using the returned object property
    const container = useRef();
    const { contextSafe } = useGSAP({ scope: container });
    
    const onClickGood = contextSafe(() => {
        gsap.to(".good", { rotation: 180 });
    });
    
    // Method 2: Using the 2nd argument inside useGSAP
    useGSAP((context, contextSafe) => {
        const onClickGood = contextSafe(() => {
            gsap.to(".good", { rotation: 180 });
        });
        
        goodRef.current.addEventListener("click", onClickGood);
        
        return () => {
            goodRef.current.removeEventListener("click", onClickGood);
        };
    }, { scope: container });
  2. Use scope to simplify selector text

    main

    By providing a scope (a React Ref) in the useGSAP() configuration object, any selector text used inside the hook (e.g., ".box") will only find descendants of that specific element. This eliminates the need to create individual useRef() hooks for every single element you want to animate and prevents accidental selection of elements outside your component instance.

    const container = useRef();
    
    useGSAP(() => {
        // This will only find elements with class "box" inside the container ref
        gsap.from(".box", { opacity: 0, stagger: 0.1 });
    }, { scope: container });
    
    return (
        <div ref={container}>
            <div className="box"></div>
            <div className="box"></div>
            <div className="box"></div>
        </div>
    );
  3. Use the useGSAP() hook

    main

    The useGSAP() hook is a drop-in replacement for useEffect() or useLayoutEffect() that automatically handles GSAP cleanup using gsap.context(). It is safer for SSR as it implements an isomorphic layout effect pattern.

    To use it, it is recommended to register it as a plugin first:

    import gsap from "gsap";
    import { useGSAP } from "@gsap/react";
    
    gsap.registerPlugin(useGSAP);
    import { useRef } from "react";
    import gsap from "gsap";
    import { useGSAP } from "@gsap/react";
    
    gsap.registerPlugin(useGSAP);
    
    const container = useRef();
    useGSAP(() => {
        // gsap code here...
    }, { scope: container });
  4. Configure useGSAP() with dependencies and scope

    main

    The useGSAP() hook accepts a configuration object as its second argument to provide maximum flexibility.

    Key configuration options:

    • scope: A React Ref that limits selector text to descendants of that element.
    • dependencies: An array of dependencies that trigger the hook.
    • revertOnUpdate: A boolean. If true, GSAP objects will be reverted every time the hook updates (when dependencies change). If false (default), they are only reverted when the hook is torn down.

    Available method signatures:

    • useGSAP(func, config): Most flexible, using a config object.
    • useGSAP(func): Simplest form, defaults to an empty dependency array.
    • useGSAP(func, dependencies): Similar to useEffect() signature.
    • const { context, contextSafe } = useGSAP(config): Returns context and contextSafe for use in event handlers.
    // Using the config object for maximum flexibility
    useGSAP(() => {
        // gsap code here...
    }, { 
        dependencies: [endX], 
        scope: container, 
        revertOnUpdate: true 
    });
  5. Use the useGSAP() hook for GSAP animations

    main

    The useGSAP() hook is the recommended way to use GSAP within React components. It manages GSAP animation lifecycles, handles automatic cleanup (reverting animations) when components unmount or dependencies change, and provides a scoped context for animations.

    Signature

    useGSAP(callback, dependencies) or useGSAP(config)

    Usage Patterns

    1. Using a callback and dependency array

    Pass a function containing your GSAP code and an optional array of dependencies.

    useGSAP(() => {
      gsap.to('.box', { x: 100 });
    }, { dependencies: [someVar] });

    2. Using a configuration object

    You can pass a single object as the argument. This is useful for defining scope and revertOnUpdate.

    useGSAP({
      dependencies: [someVar],
      scope: myRef.current,
      revertOnUpdate: true
    }, () => {
      gsap.to('.box', { x: 100 });
    });

    Return Value

    The hook returns an object containing:

    • context: The GSAP Context instance created for this hook.
    • contextSafe: A function used to wrap event handlers or callbacks that should be part of the GSAP context (ensuring they are cleaned up properly).

    Configuration Options

    • scope: A selector target (like a DOM element or a React Ref) that limits the scope of selector strings used inside the callback.
    • dependencies: An array of dependencies that trigger the effect to re-run.
    • revertOnUpdate: A boolean determining how cleanup is handled when dependencies change.
    import { useGSAP } from "@gsap/react";
    
    // Basic usage
    useGSAP(() => {
      gsap.to(".box", { rotation: 360 });
    });
    
    // Usage with scope and dependencies
    const container = useRef();
    useGSAP(() => {
      gsap.to(".box", { x: 100 });
    }, { dependencies: [someState], scope: container });
  6. Register a custom GSAP instance with useGSAP

    main

    If your application uses a specific instance of GSAP (for example, if you have multiple versions loaded or are using a specialized build), you can tell useGSAP to use that instance by calling useGSAP.register(gsapInstance).

    import { useGSAP } from "@gsap/react";
    import gsap from "gsap";
    
    useGSAP.register(gsap);
  7. Use contextSafe() for event handlers and callbacks

    main

    When using useGSAP(), any functions that are called outside of the initial animation lifecycle (such as event listeners or user-triggered callbacks) should be wrapped with contextSafe(). This ensures that these functions are added to the GSAP context and are properly cleaned up when the component unmounts or the context reverts.

    contextSafe() is returned by the useGSAP() hook.

    const { contextSafe } = useGSAP(() => {
      // initial animations
    });
    
    const onClick = contextSafe(() => {
      // This animation is now part of the GSAP context and will be cleaned up
      gsap.to(".box", { x: 100 });
    });
    
    return <div onClick={onClick} />;