Reputation: 191
I have to create some complex animations. It was cool to develop them with jQuery or VanillaJS, but I guess that I should choose another way with React. Google gave me ReactCSSTransitionGroup but it seems to be broken and unmaintained (according to this message: github.com). E.g. I can't make a delay before starting the animation.
I also found a library called React-motion but I'm not sure if it's actually a tool that I need. So I want to ask whether you can recommend me something about it. Probably I should use VanillaJS (using refs and other ReactDOM functions)? Or there is another approach to it? Thanks in advance.
Upvotes: 2
Views: 3030
Reputation: 3218
The easiest way to do animations in React, or, in fact, anywhere on the web, is to use CSS Transitions.
CSS Transitions actually has nothing to do with React. Quoting MDN,
CSS Transitions is a module of CSS that lets you create gradual transitions between the values of specific CSS properties. The behavior of these transitions can be controlled by specifying their timing function, duration, and other attributes.
Because CSS transitions is a pure CSS, they can be used in React applications, Angular, plain Javascript or even old-school server-rendered pages with no Javascript at all.
It is not the most versatile or powerful technique. But since in most cases the animations we want are pretty simple, why looking for something more complicated when a simple will do the job?
CSS Transitions are also well-supported by all major browsers with a notable exception of Opera Mini and IE below version 10.
CSS Transitions give us an ability to animate between the two CSS states. Let's say you want to animate opening and closing of a drawer (triggered by a click on a button). Let's assume we have a flex container around the drawer. When the drawer is opened, we want it to occupy 100% of the container width, therefore its max-width
should be 100%. When it is closed, its width should be 0. We can create two CSS styles:
/* This CSS style is applied when the drawer is opened */
const openedStyle = {
maxWidth: '100%' /* max-with is 100% when the drawer is opened */,
};
/* This CSS style is applied when the drawer is closed */
const closedStyle = {
maxWidth: 0 /* max-width is 0 in the closed drawer */,
};
Then we handle opening / closing event apply one of those classes to the drawer object on opening / closing:
class Drawer extends React.Component {
state = {
opened: false // Initially search form is Closed
};
toggleOpened = () =>
// Toggle opened / closed state.
// Because we rely on the previous state, we need to use
// a functional setState form
// https://ozmoroz.com/2018/11/why-my-setstate-doesnt-work/
this.setState(state => ({ ...state, opened: !state.opened }));
render() {
const { opened } = this.state;
return (
<div className="drawer-container col-12 col-md-4">
<input
type="text"
className="drawer"
// Apply 'openedStyle' CSS class if the drawer is opened,
// and 'closedStyle' if the drawer is closed.
style={opened ? openedStyle : closedStyle}
/>
<button
type="button"
className="open-close-button btn btn-primary"
onClick={this.toggleOpened}
>
{opened ? 'Close' : 'Open'}
</button>
</div>
);
}
}
export default Drawer;
When we press the "Open / Close" button, the drawer will flip between 0 and 100% width, effectively opening and closing.
All we need now is to animate it.
For that we need a secret ingredient - a CSS transition
property. All we need to do is to add the following style to the drawer:
/* This CSS style is applied when the drawer is opened */
const openedStyle = {
maxWidth: '100%' /* max-with is 100% when the drawer is opened */,
/* Upon transitioning to Open,
animate `max-width' for 0.5s*/
transition: 'max-width 0.5s'
};
/* This CSS style is applied when the drawer is closed */
const closedStyle = {
maxWidth: 0 /* max-width is 0 in the closed drawer */,
/* Upon transitioning to Closed,
animate `max-width' for 0.5s */
transition: 'max-width 0.5s'
};
Voilà! We've got our animation - upon clicking the button our drawer is now expanded and collapsed within half a second!
This is it in the nutshell, but there is more to it:
I wrote an expanded blog post explaining all the above: Painless React Animations via CSS Transitions.
Upvotes: 3
Reputation: 8308
Check out this easy to use and popular package:
https://www.npmjs.com/package/react-transition-group
Install:
npm install react-transition-group
Usage:
import { CSSTransition } from 'react-transition-group';
<CSSTransition
in={toShow} // boolean value passed via state/props to either mount or unmount this component
timeout={300}
classNames='my-element' // IMP!
unmountOnExit
>
<ComponentToBeAnimated />
</CSSTransition>
NOTE: Make sure to apply below styles using the class property in CSS:
.my-element-enter {
opacity: 0;
transform: scale(0.9);
}
.my-element-enter-active {
opacity: 1;
transform: translateX(0);
transition: opacity 300ms, transform 300ms;
}
.my-element-exit {
opacity: 1;
}
.my-element-exit-active {
opacity: 0;
transform: scale(0.9);
transition: opacity 300ms, transform 300ms;
}
Upvotes: 1