如何使用styled-components结合react-animations实现滑入与滑出动画
Hey there! Let's figure out how to add both slide-in and slide-out animations to your component. The main problem with your current code is that switching directly to display: none removes the element immediately—so the slide-out animation never gets a chance to play. Here's a couple of solid approaches using styled-components and react-animations:
Approach 1: Using Keyframes with Visibility/Opacity
This method leverages the pre-built animations from react-animations, and ensures the element stays in the DOM long enough for the slide-out to complete:
import styled, { keyframes } from 'styled-components'; import { ifProp } from 'styled-tools'; import { slideInDown, slideOutUp } from 'react-animations'; // Define both slide-in and slide-out keyframes const slideInAnimation = keyframes`${slideInDown}`; const slideOutAnimation = keyframes`${slideOutUp}`; const MyComponent = styled.div` // Base state: hidden, transparent, no height opacity: 0; visibility: hidden; max-height: 0; overflow: hidden; // When active: trigger slide-in, show the component ${ifProp('isActive', ` opacity: 1; visibility: visible; max-height: 600px; // Adjust based on your content's max height animation: 0.4s ${slideInAnimation} forwards; `)} // When inactive: trigger slide-out, keep element in DOM until animation ends ${ifProp('!isActive', ` animation: 0.4s ${slideOutAnimation} forwards; `)} `;
Key Details:
forwardsin the animation rule makes the element stay in the animation's final state (so after sliding out, it stays transparent and hidden).max-heightandoverflow: hiddenprevent the component from taking up space when hidden, while letting it expand during the slide-in.- To optimize performance, you can add an
onAnimationEndhandler to setdisplay: noneafter the slide-out finishes:import { useRef, useState } from 'react'; function ParentComponent() { const [isActive, setIsActive] = useState(false); const componentRef = useRef(null); const handleAnimationEnd = () => { if (!isActive) { componentRef.current.style.display = 'none'; } }; return ( <> <button onClick={() => setIsActive(!isActive)}>Toggle Component</button> <MyComponent isActive={isActive} ref={componentRef} onAnimationEnd={handleAnimationEnd} > {/* Your component content here */} </MyComponent> </> ); }
Approach 2: Using CSS Transitions (Simpler Alternative)
If you don't need the exact react-animations presets, you can use CSS transitions for a more lightweight solution:
import styled from 'styled-components'; import { ifProp } from 'styled-tools'; const MyComponent = styled.div` // Base state: shifted up, transparent, hidden transform: translateY(-100%); opacity: 0; visibility: hidden; transition: transform 0.4s ease, opacity 0.4s ease, visibility 0.4s ease; // When active: reset position, show component ${ifProp('isActive', ` transform: translateY(0); opacity: 1; visibility: visible; `)} `;
This works because transitions smoothly animate the changes between states—when isActive flips to false, the component slides back up and fades out naturally.
Final Notes
- Avoid
display: nonefor immediate toggles if you want animations to play—always let the element stay in the DOM until the animation completes. - Adjust the duration (
0.4s) and animation curves to match your design needs.
内容的提问来源于stack exchange,提问作者Barry Michael Doyle

