CSS Animations with React?Hooks
Matthew Steele
Lead Developer, Front End | Garrett Brands | Garrett Popcorn Shops
Animate your application with cleaner state changes and attribute selectors.
Welcome to the world of Function Components! With the addition of Hooks in early 2019’s React v16.8, practicality and minimalism are the focus. How does this influence animation? This article dives into that concept highlighting how I combined React Hooks like useState and useEffect with CSS keyframes and attribute selectors.
After learning React and subsequently eliminating the need for Class Components and lifecycle methods with Hooks, covering animations in this article is a level-up from my last animation write-up — which covered no framework, vanilla Javascript animations. Straightforward to implement and adjust, animations are now more exciting to create!
Essentially, we set an initial state, listen for changes to the state and conditionally animate our components based on the state value. For this article, I will focus on combining and implementing these concepts and have included more resources towards the end. If you are not familiar with React Hooks basics, take a moment to watch these quick tutorials.
- YouTube — Learn useState in 15 Minutes, React Hooks Explained
- YouTube — Learn useEffect in 13 Minutes, React Hooks Explained
Animations:
I created and deployed a simple React application—&Hearts—solely for this article—to illustrate the simplicity of implementing this approach. Play around with the functionality and check out the full code while you read along. By combining the concepts discussed below, we create an animated heart component that loads with animation and changes animation when clicked. Additionally, the click event triggers a separate heart icon component’s notification animation.
Animation Environment Setup ↓
To get an application moving and seamlessly engage CSS animations with React Hooks, setting up an animation environment is fundamental. What does it mean to set up an animation environment? First, isolate elements of a React application to individual components if animating them. Then, build their minimum functionality making sure that parents are communicating with children, etc. For example, our heart button and heart icon are static until clicked. Lift the state, test your onClick function using console.log—animations will never work if the component is not functioning.
There are different ways to create an animate-able element. Choose the method that fits you and your application. &Hearts’ heart button and heart icon are png assets rendered via the React image tag.
Hooks Setup ↓
1. Parent Component — Toggle State
Now that our environment is ready, we can set up our primary React hook that ultimately activates or deactivates both animations. Later, we create two additional React Hooks within each animated component, used during CSS Configuration. In this scenario, we lift state to the parent component so both children can eventually respond with animations.
We activate our child component’s animations with a click event. So, in our parent component, we create a toggle state with React’s useState hook set to a boolean value.
Subsequently, we pass down the toggle’s boolean value to our animated components via props so each component eventually knows whether to activate or deactivate animations. Each time we click on the heart component, our toggle’s state is set to the opposite value via the handleClick callback prop and function.
2. Child Components — Animation State
Next, we create additional animation state values in each child component with an initial value of zero. Eventually, the values stored in each local state will be used in our CSS Configuration, determining whether or not our animations are active.
How do we update each animation state based on our toggle value? Introducing, useEffect. This hook combines the power of lifecycle methods like componentDidMount and componentDidUpdate in a more manageable way. We can attach a conditional dependency, noting any changes to the value of [toggle] and running renderAnimations with each change. In this scenario, clicking the heart button updates the toggle value, and each child component’s animation state changes according to the value.
CSS Configuration ↓
Awesome! Our animation environment is ready, and our hooks are set up and communicating effectively at each level. With this, we can move forward, configure our CSS and enable our animations!
Start by adding an animation attribute to each component set equal to the animation state. Remember, our React components return HTML, so we add animation={animation} to our image tag.
Next, we add animation keyframes to our CSS stylesheet. For this blog and demo application, I used a handy tool called Animista to select an animation and generate keyframes. Tip: Make sure to minify your keyframes before copying them into your stylesheet.
For a more in-depth look at keyframes, check out my previous blog post.
Finally, we activate this animation by adding a CSS attribute selector in our stylesheet using our component’s class name and our new animation attribute. You can find animation properties like name and duration when you select the animation on Animista.
If we set up everything correctly, clicking on our heart will update our toggle value and animation state/attribute [animation="1"] — thus activating our jello-horizontal animation.
Conclusion
Using React Hooks eliminates the need for Class Components and lifecycle methods. Additionally, it provides a cleaner and more manageable approach for activating/deactivating CSS animations. Please check out some of the resources I’ve listed below for continued learning and working. If you have any questions, don’t hesitate to reach out at [email protected]!
Resources
- &Hearts App — GitHub
- Animista — Keyframes generator
- CSS Tricks — Attribute Selectors
- Netlify — Simple React Application Deployment
- YouTube— Learn useState in 15 Minutes, React Hooks Explained
- YouTube— Learn useEffect in 13 Minutes, React Hooks Explained
Clojure SaaS boilerplate ?? shipclojure.com
2 年This was exactly what I was looking for! Thank you man!
Software Engineer | Full-Stack | Ruby, SQL, Sinatra, Rails, Redux, React, JavaScript, HTML5, and SCSS/CSS3
3 年These are awesome! Thanks for sharing Matthew Steele (he/him)