A transition component inspired by the excellent
ng-animate library, you should
use it if you're using CSS transitions or animations. It's built upon the
Transition
component, so it inherits all of its props.
CSSTransition applies a pair of class names during the appear, enter,
and exit states of the transition. The first class is applied and then a
second *-active class in order to activate the CSS transition. After the
transition, matching *-done class names are applied to persist the
transition state.
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>
);
}When the in prop is set to true, the child component will first receive
the class example-enter, then the example-enter-active will be added in
the next tick. CSSTransition forces a
reflow
between before adding the example-enter-active. This is an important trick
because it allows us to transition between example-enter and
example-enter-active even though they were added immediately one after
another. Most notably, this is what makes it possible for us to animate
appearance.
.my-node-enter {
opacity: 0;
}
.my-node-enter-active {
opacity: 1;
transition: opacity 200ms;
}
.my-node-exit {
opacity: 1;
}
.my-node-exit-active {
opacity: 0;
transition: opacity 200ms;
}*-active classes represent which styles you want to animate to, so it's
important to add transition declaration only to them, otherwise transitions
might not behave as intended! This might not be obvious when the transitions
are symmetrical, i.e. when *-enter-active is the same as *-exit, like in
the example above (minus transition), but it becomes apparent in more
complex transitions.
Note: If you're using the
appear
prop, make sure to define styles for .appear-* classes as well.
<Transition> unless otherwise noted.classNames The animation classNames applied to the component as it appears, enters,
exits or has finished the transition. A single name can be provided, which
will be suffixed for each stage, e.g. classNames="fade" applies:
fade-appear, fade-appear-active, fade-appear-donefade-enter, fade-enter-active, fade-enter-donefade-exit, fade-exit-active, fade-exit-doneA few details to note about how these classes are applied:
className without worrying that it will be overridden.in={false}, no classes are
applied yet. You might be expecting *-exit-done, but if you think
about it, a component cannot finish exiting if it hasn't entered yet.fade-appear-done and fade-enter-done will both be applied. This
allows you to define different behavior for when appearing is done and
when regular entering is done, using selectors like
.fade-enter-done:not(.fade-appear-done). For example, you could apply
an epic entrance animation when element first appears in the DOM using
Animate.css. Otherwise you can
simply use fade-enter-done for defining both cases.Each individual classNames can also be specified independently like:
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',
}}If you want to set these classes using CSS Modules:
import styles from './styles.css';you might want to use camelCase in your CSS file, that way could simply spread them instead of listing them one by one:
classNames={{ ...styles }}string | {
appear?: string,
appearActive?: string,
appearDone?: string,
enter?: string,
enterActive?: string,
enterDone?: string,
exit?: string,
exitActive?: string,
exitDone?: string,
}''onEnter A <Transition> callback fired immediately after the 'enter' or 'appear' class is
applied.
Note: when nodeRef prop is passed, node is not passed, so isAppearing is being passed as the first argument.
Function(node: HtmlElement, isAppearing: bool)onEntering A <Transition> callback fired immediately after the 'enter-active' or
'appear-active' class is applied.
Note: when nodeRef prop is passed, node is not passed, so isAppearing is being passed as the first argument.
Function(node: HtmlElement, isAppearing: bool)onEntered A <Transition> callback fired immediately after the 'enter' or
'appear' classes are removed and the done class is added to the DOM node.
Note: when nodeRef prop is passed, node is not passed, so isAppearing is being passed as the first argument.
Function(node: HtmlElement, isAppearing: bool)onExit A <Transition> callback fired immediately after the 'exit' class is
applied.
Note: when nodeRef prop is passed, node is not passed
Function(node: HtmlElement)onExiting A <Transition> callback fired immediately after the 'exit-active' is applied.
Note: when nodeRef prop is passed, node is not passed
Function(node: HtmlElement)onExited A <Transition> callback fired immediately after the 'exit' classes
are removed and the exit-done class is added to the DOM node.
Note: when nodeRef prop is passed, node is not passed
Function(node: HtmlElement)