The Transition component lets you describe a transition from one component state to another over time with a simple declarative API. It tracks "enter" and "exit" states for components without applying any styling - that's up to you.
Core transition component providing lifecycle management for entering and exiting elements.
/**
* The Transition component lets you describe a transition from one component
* state to another over time with a simple declarative API.
*/
declare class Transition<RefElement extends HTMLElement | undefined> extends Component<TransitionProps<RefElement>> {}
type TransitionProps<RefElement extends undefined | HTMLElement = undefined> =
| TimeoutProps<RefElement>
| EndListenerProps<RefElement>;Core properties shared by all transition configurations.
interface BaseTransitionProps<RefElement extends undefined | HTMLElement> extends TransitionActions {
/** Show the component; triggers the enter or exit states */
in?: boolean;
/** Lazy mount the component on the first `in={true}` */
mountOnEnter?: boolean;
/** Unmount the component after it finishes exiting */
unmountOnExit?: boolean;
/** Callback fired before the "entering" status is applied */
onEnter?: EnterHandler<RefElement>;
/** Callback fired after the "entering" status is applied */
onEntering?: EnterHandler<RefElement>;
/** Callback fired after the "entered" status is applied */
onEntered?: EnterHandler<RefElement>;
/** Callback fired before the "exiting" status is applied */
onExit?: ExitHandler<RefElement>;
/** Callback fired after the "exiting" status is applied */
onExiting?: ExitHandler<RefElement>;
/** Callback fired after the "exited" status is applied */
onExited?: ExitHandler<RefElement>;
/** Function child or React element */
children?: TransitionChildren;
/** React reference to DOM element that needs to transition */
nodeRef?: React.Ref<RefElement>;
[prop: string]: any;
}Configuration for transitions using explicit timeout durations.
interface TimeoutProps<RefElement extends undefined | HTMLElement> extends BaseTransitionProps<RefElement> {
/**
* The duration of the transition, in milliseconds.
* Can be a single number or object with appear/enter/exit values.
*/
timeout: number | {
appear?: number;
enter?: number;
exit?: number;
};
/** Custom transition end trigger with timeout fallback */
addEndListener?: EndHandler<RefElement>;
}Configuration for transitions using custom end detection logic.
interface EndListenerProps<RefElement extends undefined | HTMLElement> extends BaseTransitionProps<RefElement> {
/** Optional timeout as fallback */
timeout?: number | {
appear?: number;
enter?: number;
exit?: number;
};
/** Required custom transition end trigger */
addEndListener: EndHandler<RefElement>;
}Base configuration for transition behavior.
interface TransitionActions {
/** Transition on first mount if true */
appear?: boolean;
/** Enable or disable enter transitions */
enter?: boolean;
/** Enable or disable exit transitions */
exit?: boolean;
}type EnterHandler<RefElement extends undefined | HTMLElement> = RefElement extends undefined
? (isAppearing: boolean) => void
: (node: HTMLElement, isAppearing: boolean) => void;
type ExitHandler<RefElement extends undefined | HTMLElement> = RefElement extends undefined
? () => void
: (node: HTMLElement) => void;
type EndHandler<RefElement extends undefined | HTMLElement> = RefElement extends undefined
? (done: () => void) => void
: (node: HTMLElement, done: () => void) => void;type TransitionStatus = "entering" | "entered" | "exiting" | "exited" | "unmounted";
const UNMOUNTED = "unmounted";
const EXITED = "exited";
const ENTERING = "entering";
const ENTERED = "entered";
const EXITING = "exiting";
type TransitionChildren =
| ReactNode
| ((status: TransitionStatus, childProps?: Record<string, unknown>) => ReactNode);Usage Examples:
import React, { useState, useRef } from "react";
import { Transition } from "react-transition-group";
// Basic transition with render prop
const FadeTransition: React.FC = () => {
const [show, setShow] = useState(false);
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 },
};
return (
<>
<button onClick={() => setShow(!show)}>Toggle</button>
<Transition in={show} timeout={duration}>
{state => (
<div style={{
...defaultStyle,
...transitionStyles[state]
}}>
I'm a fade transition!
</div>
)}
</Transition>
</>
);
};
// Using nodeRef for direct DOM access
const RefTransition: React.FC = () => {
const [show, setShow] = useState(false);
const nodeRef = useRef<HTMLDivElement>(null);
return (
<>
<button onClick={() => setShow(!show)}>Toggle</button>
<Transition
nodeRef={nodeRef}
in={show}
timeout={300}
onEnter={() => console.log('Entering')}
onExited={() => console.log('Exited')}
>
<div ref={nodeRef}>Content with ref</div>
</Transition>
</>
);
};