June 12, 2018
In general animating the view is hard, because suddenly the state is dependent on time. Views can exist longer than they existed before because of exit animations, or some layouts must wait for other elements to take their place. And animations are expensive, so don’t do too much and whenever possible you should use hardware accelerated key-frame animations or transitions. But sometimes the animations get a little more complex and are difficult to handle with pure css and style rules. Then it’s time to take some animations library to help.
One of the large goals of react is to describe as much of the app in a declarative way, for styling the styled-components workflow is working really good and react-pose has a similar api to animate components. Instead of styles you define different “poses” the component can have and define how the transitions of values between the poses should work.
For example a sidebar component which can be hidden on the left side of the screen would look like this:
import posed from "react-pose"; const Sidebar = posed.nav({ open: { x: "0%", // animate child components with 100ms between entries staggerChildren: 100, }, closed: { x: "-100%" }, }); const NavItem = posed.li({ open: { opacity: 1 }, closed: { opacity: 0 }, }); export default ({ isOpen, navItems }) => ( <Sidebar pose={isOpen ? "open" : "closed"}> <ul> {navItems.map(({ url, name }) => ( <NavItem> <a href={url}>{name}</a> </NavItem> ))} </ul> </Sidebar> );
If you want to have enter and exit animations you need a
Wrapper Component managing newly created and disappearing
components. With react-pose you can use the PoseGroup
to
manage posed components. Every direct child of a PoseGroup
will get the poses enter
and exit
and needs a unique
key
prop to enabled tracking of the elements.
const Item = posed.div({ enter: { opacity: 1 }, exit: { opacity: 0 }, }); const ItemList = ({ items }) => ( <PoseGroup> {items.map(item => <Item key={item.id} />)} </PoseGroup> );
As an exercise try to rebuild this animation from dribble, a working result could look like this:
As a basis you can use this repository
Written by Kalle Ott for opencampus