Exploring Animation Hooks with Framer Motion in React
Written on
Chapter 1: Introduction to Framer Motion
The Framer Motion library simplifies the process of adding animations to React applications. It offers a variety of hooks that allow developers to create engaging and dynamic user interfaces.
In this article, we will explore how to effectively use Framer Motion's hooks to enhance animations based on user settings and component presence.
Section 1.1: Utilizing the useReducedMotion Hook
The useReducedMotion hook allows us to tailor animations based on the device's motion preferences. For instance, we can adjust how elements animate when the reduced motion setting is active. Here's an example implementation:
import React, { useState } from "react";
import { motion, useReducedMotion } from "framer-motion";
export default function App() {
const shouldReduceMotion = useReducedMotion();
const closedX = shouldReduceMotion ? 0 : "-100%";
const [isOpen, setIsOpen] = useState(true);
return (
<>
<button onClick={() => setIsOpen(!isOpen)}>Toggle</button>
<motion.div initial={{ x: closedX }} animate={{ x: 0 }} />
</>
);
}
In the code above, we leverage the useReducedMotion hook to determine whether to apply reduced motion settings and adjust the position of the animated div accordingly.
Section 1.2: Understanding the usePresence Hook
The usePresence hook helps track whether an element is still part of the React component tree. When isPresent returns false, it indicates that the component is being removed, but the AnimatePresence component won't eliminate it until safeToRemove is called. Here's how it works:
import React, { useEffect, useState } from "react";
import { usePresence } from "framer-motion";
export const Component = () => {
const [isPresent, safeToRemove] = usePresence();
useEffect(() => {
console.log(isPresent);
if (!isPresent) {
setTimeout(safeToRemove, 1000);}
}, [isPresent]);
return <div />;
};
export default function App() {
const [isOpen, setIsOpen] = useState(true);
return (
<>
<button onClick={() => setIsOpen(!isOpen)}>Toggle</button>
{isOpen && <Component />}
</>
);
}
In this example, we monitor the isPresent value within the useEffect hook and invoke safeToRemove to clean up the component when it is no longer needed.
Section 1.3: Exploring the useIsPresent Hook
Similar to usePresence, the useIsPresent hook provides a way to check if a component is currently rendered but does not include the safeToRemove function. Here’s a demonstration:
import React, { useEffect, useState } from "react";
import { useIsPresent } from "framer-motion";
export const Component = () => {
const isPresent = useIsPresent();
useEffect(() => {
if (isPresent) {
console.log("Component is present");}
}, [isPresent]);
return <div />;
};
export default function App() {
const [isOpen, setIsOpen] = useState(true);
return (
<>
<button onClick={() => setIsOpen(!isOpen)}>Toggle</button>
{isOpen && <Component />}
</>
);
}
This code logs a message whenever the component is active, providing insight into its rendering state.
Chapter 2: Implementing Drag Controls
The useDragControls hook enables the creation of draggable components. These controls can be attached to a draggable element, allowing for intuitive user interactions. Here's how to set it up:
import { motion, useDragControls } from "framer-motion";
import React from "react";
export default function App() {
const dragControls = useDragControls();
function startDrag(event) {
dragControls.start(event, { snapToCursor: true });}
return (
<>
<motion.div drag="x" dragControls={dragControls} onPointerDown={startDrag}>
Click Me</motion.div>
</>
);
}
By using the useDragControls hook, we can initiate dragging when the user interacts with the component, enhancing the overall user experience.
In the first video, "Complex Animations with Framer Motion & React || useAnimate Hook," viewers will learn advanced animation techniques using the Framer Motion library.
The second video, "Animation with Framer-Motion - #8 useAnimation hook," provides insights into using the useAnimation hook for more controlled animations.