如何使用React-Spring的useSprings仅为数组中激活按钮添加动画
问题排查与修正方案
你代码里存在几个核心问题导致动画不生效,逐一修正即可:
- 缺失
useState导入:代码中使用了React的useState钩子,但没有从react包引入,会直接运行报错 - 没有用
animated包裹目标组件:react-spring的动画属性必须绑定到经过animated处理的组件上才能触发过渡效果,你现在用的普通styled组件不会响应弹簧动画值 useSprings没有配置响应式更新:当前你传入的是静态配置数组,activeBox变化时不会触发弹簧动画重新计算,需要加上依赖项监听状态变化
修正后完整代码
import { useState } from "react"; import { useSprings, animated } from "react-spring"; import styled from "styled-components"; // 记得先导入你用到的四个图片资源box1/box2/box3/box4 import box1 from "你的图片1路径"; import box2 from "你的图片2路径"; import box3 from "你的图片3路径"; import box4 from "你的图片4路径"; const Nav = () => { // Set Active Box const [activeBox, setActiveBox] = useState(0); const handleClick = (index) => { setActiveBox(index); }; // Boxes const boxes = [box1, box2, box3, box4]; // useSprings 新增依赖项监听activeBox变化 const springs = useSprings( boxes.length, boxes.map((box, index) => ({ marginTop: activeBox === index ? 50 : 0, })), [activeBox] ); return ( <NavContainer> {springs.map((prop, index) => ( // 替换为经过animated处理的组件 <AnimatedBox style={prop} key={index} onClick={() => handleClick(index)} currentActiveBox={activeBox === index} > <img src={boxes[index]} alt="" /> </AnimatedBox> ))} </NavContainer> ); }; export default Nav; const NavContainer = styled.div` position: absolute; bottom: 0; width: 200px; height: 75px; /* 如果需要盒子横向排列,保留下面两行配置,否则默认纵向排列 */ display: flex; align-items: flex-end; gap: 10px; `; const StyledBox = styled.div` width: 25px; height: 25px; img { width: 100%; height: 100%; } `; // 用animated包裹styled组件,让其支持动画属性 const AnimatedBox = animated(StyledBox);
如果需要调整动画的速度、弹性效果,可以在useSprings的配置里新增tension、friction参数自定义动画曲线。
内容的提问来源于stack exchange,提问作者SheShellSheShore
相关产品推荐
相关产品推荐

