TransitionGroup manages a set of Transition components in a list. It automatically handles mounting and unmounting of child components, making it ideal for animating dynamic lists.
Component for managing multiple child transitions in dynamic lists.
/**
* The TransitionGroup component manages a set of Transition components in a list.
* It automatically toggles the `in` prop for child transitions when items are
* added or removed from the list.
*/
declare class TransitionGroup extends Component<TransitionGroupProps> {}Configuration for transition group behavior and rendering.
type TransitionGroupProps<T extends keyof JSX.IntrinsicElements = "div", V extends ElementType = any> =
| (IntrinsicTransitionGroupProps<T> & JSX.IntrinsicElements[T])
| (ComponentTransitionGroupProps<V>) & {
/** Child Transition or CSSTransition components */
children?: ReactElement<TransitionProps<any>> | Array<ReactElement<TransitionProps<any>>>;
/** Transform child elements before rendering */
childFactory?(child: ReactElement): ReactElement;
[prop: string]: any;
};Props when using standard HTML elements as the wrapper.
interface IntrinsicTransitionGroupProps<T extends keyof JSX.IntrinsicElements = "div"> extends TransitionActions {
/** HTML element type to render as wrapper (default: "div") */
component?: T | null;
}Props when using a custom React component as the wrapper.
interface ComponentTransitionGroupProps<T extends ElementType> extends TransitionActions {
/** Custom React component to render as wrapper */
component: T;
}Inherited actions applied to all child transitions.
interface TransitionActions {
/** Enable appear transitions for all children */
appear?: boolean;
/** Enable enter transitions for all children */
enter?: boolean;
/** Enable exit transitions for all children */
exit?: boolean;
}in={true} for new childrenin={false} for removed childrenkey props<div> by default, but can be customized with component propUsage Examples:
import React, { useState } from "react";
import { TransitionGroup, CSSTransition } from "react-transition-group";
// Basic list with add/remove
const TodoList: React.FC = () => {
const [items, setItems] = useState(["hello", "world", "click", "me"]);
const handleAdd = () => {
const newItem = prompt("Enter some text");
if (newItem) {
setItems([...items, newItem]);
}
};
const handleRemove = (index: number) => {
setItems(items.filter((_, i) => i !== index));
};
return (
<div>
<button onClick={handleAdd}>Add Item</button>
<TransitionGroup>
{items.map((item, index) => (
<CSSTransition
key={item}
timeout={300}
classNames="list-item"
>
<div className="list-item">
{item}{" "}
<button onClick={() => handleRemove(index)}>
Remove
</button>
</div>
</CSSTransition>
))}
</TransitionGroup>
</div>
);
};
// Custom wrapper component
const CardList: React.FC = () => {
const [cards, setCards] = useState([
{ id: 1, title: "Card 1" },
{ id: 2, title: "Card 2" },
]);
return (
<TransitionGroup component="ul" className="card-list">
{cards.map((card) => (
<CSSTransition
key={card.id}
timeout={500}
classNames="card"
>
<li className="card">
<h3>{card.title}</h3>
<button onClick={() => setCards(cards.filter(c => c.id !== card.id))}>
Delete
</button>
</li>
</CSSTransition>
))}
</TransitionGroup>
);
};
// Without wrapper element
const InlineList: React.FC = () => {
const [tags, setTags] = useState(["react", "typescript", "animation"]);
return (
<div>
<TransitionGroup component={null}>
{tags.map((tag) => (
<CSSTransition
key={tag}
timeout={200}
classNames="tag"
>
<span className="tag">
{tag}
<button onClick={() => setTags(tags.filter(t => t !== tag))}>
×
</button>
</span>
</CSSTransition>
))}
</TransitionGroup>
</div>
);
};
// With childFactory for custom transformations
const CustomTransformList: React.FC = () => {
const [items, setItems] = useState(["Item 1", "Item 2"]);
const [highlight, setHighlight] = useState(false);
return (
<div>
<button onClick={() => setHighlight(!highlight)}>
Toggle Highlight
</button>
<TransitionGroup
childFactory={(child) =>
React.cloneElement(child, {
classNames: highlight ? "highlight" : "normal"
})
}
>
{items.map((item, index) => (
<CSSTransition
key={item}
timeout={300}
classNames="normal"
>
<div>{item}</div>
</CSSTransition>
))}
</TransitionGroup>
</div>
);
};Important Notes:
appear={true} prop to enable appear transitions for initial itemskey propin prop of children