react-transition-group

repository·master·Indexed 27 days ago

https://github.com/reactjs/react-transition-group

A React component toolset for managing animations and component states, such as mounting and unmounting, over time. Version 4.4.5 provides components including CSSTransition for CSS-based animations, TransitionGroup for managing multiple transitions, SwitchTransition for coordinating enter/exit order, and a platform-agnostic Transition component for programmatic control.

Tokens
4.1K
Snippets
9
Records
25
Agent score
89%

What's inside react-transition-group

  1. Use `<TransitionGroup>` with `<Transition>` components

    master

    In v2, <TransitionGroup> no longer manages transitions via static lifecycle methods on its children. Instead, <TransitionGroup> injects transition-specific props into its children, which must be passed through to a <Transition> component (or <CSSTransition>) for the animation to function.

    When creating custom wrapper components for transitions, ensure you spread the incoming props onto the <Transition> component.

    const MyTransition = ({ children: child, ...props }) => (
      // The spread (...props) is required to pass injected props from TransitionGroup to Transition
      <Transition {...props}>
        {transitionState => React.cloneElement(child, {
          style: getStyleForTransitionState(transitionState)
        })}
      </Transition>
    );
    
    const MyList = () => (
      <TransitionGroup>
        {items.map(item => (
          <MyTransition key={item.id}>{item}</MyTransition>
        ))}
      </TransitionGroup>
    );
  2. Migrate from v1 to v2

    master

    When migrating from react-transition-group v1 to v2, note the following prop and component changes:

    • Replace <CSSTransitionGroup> with a combination of <TransitionGroup> and <CSSTransition>.
    • transitionName becomes classNames.
    • transitionEnterTimeout and transitionLeaveTimeout are replaced by a single timeout prop, which accepts an object: timeout={{ enter, exit }}. If both values are the same, you can use the shorthand timeout={number}.
    • transitionAppear becomes appear.
    • transitionEnter becomes enter.
    • transitionLeave becomes exit (v2 uses "exit" instead of "leave" for symmetry).

    CSS Class Changes: Because leave was renamed to exit, you must update your CSS selectors from .example-leave and .example-leave-active to .example-exit and .example-exit-active respectively.

    - transitionName="example"
    - transitionEnterTimeout={500}
    - transitionLeaveTimeout={300}
    + classNames="example"
    + timeout={{ enter: 500, exit: 300 }}
  3. Use CSSTransition for CSS-based animations

    master

    The CSSTransition component manages CSS transitions or animations by applying a pair of class names during the appear, enter, and exit states. It applies a base class (e.g., fade-enter), then an *-active class (e.g., fade-enter-active) to trigger the transition, and finally a *-done class (e.g., fade-enter-done) to persist the state.

    To use CSSTransition, provide a nodeRef to the component and pass that same ref to the child element you wish to animate. This is required to avoid using findDOMNode in Strict Mode.

    CSS Implementation Pattern: Apply the transition property only to the *-active classes. The base classes (like *-enter or *-exit) should define the starting styles.

    function App() {
      const [inProp, setInProp] = useState(false);
      const nodeRef = useRef(null);
      return (
        <div>
          <CSSTransition nodeRef={nodeRef} in={inProp} timeout={200} classNames="my-node">
            <div ref={nodeRef}>
              {"I'll receive my-node-* classes"}
            </div>
          </CSSTransition>
          <button type="button" onClick={() => setInProp(true)}>
            Click to Enter
          </button>
        </div>
      );
    }
  4. Use SwitchTransition to control render between state transitions

    master

    The SwitchTransition component allows you to control the order in which elements transition during a state change. It is useful when you want to ensure one element has finished its exit animation before the next one begins its entry animation, or vice versa.

    Modes:

    • out-in (default): The current element transitions out first. Once the exit is complete, the new element transitions in.
    • in-out: The new element transitions in first. Once the entry is complete, the current element transitions out.

    Note: If you want animations to happen simultaneously (old child removed and new child inserted at the same time), use TransitionGroup instead.

    Requirements:

    • The children must be a Transition or CSSTransition component.
    • The child component must have a unique key prop so SwitchTransition can detect when the state has changed.
    function App() {
      const [state, setState] = useState(false);
      const helloRef = useRef(null);
      const goodbyeRef = useRef(null);
      const nodeRef = state ? goodbyeRef : helloRef;
    
      return (
        <SwitchTransition mode="out-in">
          <CSSTransition
            key={state ? "Goodbye, world!" : "Hello, world!"}
            nodeRef={nodeRef}
            addEndListener={(node, done) => node.addEventListener("transitionend", done, false)}
            classNames='fade'
          >
            <button ref={nodeRef} onClick={() => setState(state => !state)}>
              {state ? "Goodbye, world!" : "Hello, world!"}
            </button>
          </CSSTransition>
        </SwitchTransition>
      );
    }
  5. Use the Transition component for platform-agnostic transitions

    master

    The Transition component allows you to describe transitions between component states over time using a declarative API. It tracks 'enter' and 'exit' states, which you can use to apply styles or trigger logic.

    Note: Transition is platform-agnostic. If you are using CSS transitions, use CSSTransition instead, as it provides additional features specifically for CSS.

    Transition supports two types of children:

    1. A function child: Receives the current transition status ('entering', 'entered', 'exiting', or 'exited') as an argument. This is useful for applying state-specific props or classes.
    2. A React element: The component will receive the transition props automatically via React.cloneElement.
    import { Transition } from 'react-transition-group';
    import { useRef } from 'react';
    
    const duration = 300;
    
    const defaultStyle = {
      transition: `opacity ${duration}ms ease-in-out`,
      opacity: 0,
    };
    
    const transitionStyles = {
      entering: { opacity: 1 },
      entered:  { opacity: 1 },
      exiting:  { opacity: 0 },
      exited:  { opacity: 0 },
    };
    
    function Fade({ in: inProp }) {
      const nodeRef = useRef(null);
      return (
        <Transition nodeRef={nodeRef} in={inProp} timeout={duration}>
          {state => (
            <div ref={nodeRef} style={{
              ...defaultStyle,
              ...transitionStyles[state]
            }}>
              I'm a fade Transition!
            </div>
          )}
        </Transition>
      );
    }
  6. Note on version compatibility and migration

    master

    The API in v2 and above is not backwards compatible with the original react-addons-transition-group (v1-stable).

    • If you require a drop-in replacement for react-addons-transition-group or react-addons-css-transition-group, you must use the v1 release.
    • For modern projects, it is recommended to upgrade to the latest version and follow the migration guide.
  7. Use `<Transition>` lifecycle callback props

    master

    Since child lifecycle methods were removed in v2, use the lifecycle callback props on the <Transition> component to perform actions when transition states change. Each callback is called with the DOM node of the transition component.

    Note that v2 provides three states per transition (entering, entered, and exiting) instead of the original two.

    <Transition
      {...props}
      onEnter={handleEnter}
      onEntering={handleEntering}
      onEntered={handleEntered}
      onExit={handleExit}
      onExiting={handleExiting}
      onExited={handleExited}
    />
  8. Configure classNames in CSSTransition

    master

    The classNames prop defines the CSS classes applied during different transition phases. It accepts either a string or an object.

    Using a string: Providing a string like classNames="fade" automatically generates the following class combinations:

    • fade-appear, fade-appear-active, fade-appear-done
    • fade-enter, fade-enter-active, fade-enter-done
    • fade-exit, fade-exit-active, fade-exit-done

    Using an object: For fine-grained control or when using CSS Modules, provide an object with specific keys. This is useful for mapping camelCase CSS module classes to the transition phases:

    classNames={{
      appear: 'my-appear',
      appearActive: 'my-active-appear',
      appearDone: 'my-done-appear',
      enter: 'my-enter',
      enterActive: 'my-active-enter',
      enterDone: 'my-done-enter',
      exit: 'my-exit',
      exitActive: 'my-active-exit',
      exitDone: 'my-done-exit',
    }}
  9. Customize transition end detection with addEndListener

    master

    If you want to use specific browser events (like transitionend) instead of relying on the timeout prop, use addEndListener.

    Note: When using nodeRef, the first argument passed to the listener is the done callback, not the node.

    <Transition
      nodeRef={nodeRef}
      in={inProp}
      timeout={500}
      addEndListener={(node, done) => {
        // use the css transitionend event to mark the finish of a transition
        node.addEventListener('transitionend', done, false);
      }}
    >
      {state => (
        <div ref={nodeRef} className={`fade-${state}`}>Content</div>
      )}
    </Transition>
  10. CSSTransition lifecycle callbacks

    master

    The CSSTransition component provides several lifecycle callbacks that fire during different stages of the transition.

    Note on arguments: When the nodeRef prop is provided, the first argument passed to these callbacks is isAppearing (boolean) instead of the node (HTMLElement). If nodeRef is NOT provided, the first argument is the node.

    CallbackTrigger Timing
    onEnterImmediately after the enter or appear class is applied.
    onEnteringImmediately after the enter-active or appear-active class is applied.
    onEnteredImmediately after the enter or appear classes are removed and the done class is added.
    onExitImmediately after the exit class is applied.
    onExitingImmediately after the exit-active class is applied.
    onExitedImmediately after the exit classes are removed and the exit-done class is added.