react-transition-group
repository·master·Indexed 27 days ago
https://github.com/reactjs/react-transition-groupA 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.
What's inside react-transition-group
- To view and interact with the library's examples, you can run the included Storybook instance. This requires cloning the repository and installing dependencies first.
Use `<TransitionGroup>` with `<Transition>` components
masterIn 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> );Migrate from v1 to v2
masterWhen migrating from
react-transition-groupv1 to v2, note the following prop and component changes:- Replace
<CSSTransitionGroup>with a combination of<TransitionGroup>and<CSSTransition>. transitionNamebecomesclassNames.transitionEnterTimeoutandtransitionLeaveTimeoutare replaced by a singletimeoutprop, which accepts an object:timeout={{ enter, exit }}. If both values are the same, you can use the shorthandtimeout={number}.transitionAppearbecomesappear.transitionEnterbecomesenter.transitionLeavebecomesexit(v2 uses "exit" instead of "leave" for symmetry).
CSS Class Changes: Because
leavewas renamed toexit, you must update your CSS selectors from.example-leaveand.example-leave-activeto.example-exitand.example-exit-activerespectively.- transitionName="example" - transitionEnterTimeout={500} - transitionLeaveTimeout={300} + classNames="example" + timeout={{ enter: 500, exit: 300 }}- Replace
Install TypeScript definitions for react-transition-group
masterTypeScript definitions for
react-transition-groupare provided via DefinitelyTyped. You can install them using npm.npm install @types/react-transition-groupUse CSSTransition for CSS-based animations
masterThe
CSSTransitioncomponent manages CSS transitions or animations by applying a pair of class names during theappear,enter, andexitstates. It applies a base class (e.g.,fade-enter), then an*-activeclass (e.g.,fade-enter-active) to trigger the transition, and finally a*-doneclass (e.g.,fade-enter-done) to persist the state.To use
CSSTransition, provide anodeRefto the component and pass that same ref to the child element you wish to animate. This is required to avoid usingfindDOMNodein Strict Mode.CSS Implementation Pattern: Apply the
transitionproperty only to the*-activeclasses. The base classes (like*-enteror*-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> ); }Use SwitchTransition to control render between state transitions
masterThe
SwitchTransitioncomponent 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
TransitionGroupinstead.Requirements:
- The
childrenmust be aTransitionorCSSTransitioncomponent. - The child component must have a unique
keyprop soSwitchTransitioncan 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> ); }Use the Transition component for platform-agnostic transitions
masterThe
Transitioncomponent 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:
Transitionis platform-agnostic. If you are using CSS transitions, useCSSTransitioninstead, as it provides additional features specifically for CSS.Transitionsupports two types of children:- 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. - 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> ); }- A function child: Receives the current transition status (
Note on version compatibility and migration
masterThe 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-grouporreact-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.
- If you require a drop-in replacement for
Use `<Transition>` lifecycle callback props
masterSince 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} />Configure classNames in CSSTransition
masterThe
classNamesprop defines the CSS classes applied during different transition phases. It accepts either astringor anobject.Using a string: Providing a string like
classNames="fade"automatically generates the following class combinations:fade-appear,fade-appear-active,fade-appear-donefade-enter,fade-enter-active,fade-enter-donefade-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', }}Customize transition end detection with addEndListener
masterIf you want to use specific browser events (like
transitionend) instead of relying on thetimeoutprop, useaddEndListener.Note: When using
nodeRef, the first argument passed to the listener is thedonecallback, 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>CSSTransition lifecycle callbacks
masterThe
CSSTransitioncomponent provides several lifecycle callbacks that fire during different stages of the transition.Note on arguments: When the
nodeRefprop is provided, the first argument passed to these callbacks isisAppearing(boolean) instead of thenode(HTMLElement). IfnodeRefis NOT provided, the first argument is thenode.Callback Trigger Timing onEnterImmediately after the enterorappearclass is applied.onEnteringImmediately after the enter-activeorappear-activeclass is applied.onEnteredImmediately after the enterorappearclasses are removed and thedoneclass is added.onExitImmediately after the exitclass is applied.onExitingImmediately after the exit-activeclass is applied.onExitedImmediately after the exitclasses are removed and theexit-doneclass is added.