framer-motion get()方法配合百分比宽度失效,如何无需额外状态实现滚动进度?
不用额外状态实现Framer Motion滚动进度条
你的第一种写法失效是因为scrollYProgress.get()仅在组件初始化时获取一次值,滚动过程中组件不会重新渲染,所以宽度不会更新。要不用额外状态实现,直接利用Framer Motion的useTransform将滚动进度值转换为百分比字符串,再绑定到样式即可:
import { ReactNode } from 'react'; import { motion, useScroll, useTransform } from 'framer-motion'; export const ScrollProgress = ({ children }: { children: ReactNode }) => { const { scrollYProgress } = useScroll(); // 将0-1的滚动进度转换为"0%"到"100%"的字符串 const widthProgress = useTransform(scrollYProgress, (value) => `${value * 100}%`); return ( <div> <motion.div style={{ transformOrigin: 'left', backgroundColor: 'blue', position: 'sticky', top: '80px', width: widthProgress, // 直接使用转换后的motionValue height: '20px', zIndex: 10, }} /> {children} </div> ); };
原理说明
useTransform会创建一个与scrollYProgress联动的新motionValue,当滚动进度变化时,它会自动计算对应的百分比字符串。- Motion组件的
style属性支持直接接收motionValue,组件会自动监听值的变化并更新DOM样式,无需通过React state触发重渲染,性能更优。
内容的提问来源于stack exchange,提问作者Merger
相关产品推荐
相关产品推荐

