React 18.3.1+Vite环境下集成Motion与Lenis的实现是否正确?
新版Motion与Lenis在React 18.3.1 + Vite项目中的集成验证
你的代码实现思路是正确的,核心逻辑符合新版motion和Lenis的集成规范——通过关闭Lenis自动RAF,改用motion的frame模块统一驱动滚动动画,避免双RAF导致的性能问题或不同步。下面逐点验证细节:
正确的部分
- 依赖导入:从
lenis/react导入ReactLenis和LenisRef,从motion/react导入frame和cancelFrame,完全匹配两个库的新版导出路径。 - Ref类型定义:
lenisRef使用LenisRef | null作为类型,准确对应ReactLenis组件的ref类型,确保TypeScript类型校验通过。 - RAF同步逻辑:关闭
ReactLenis的autoRaf选项,通过frame.update注册回调来驱动Lenis的raf方法,第二个参数true标记为高优先级回调,保证滚动动画的流畅性。 - 清理机制:在useEffect的返回函数中调用
cancelFrame移除回调,避免组件卸载后内存泄漏。
可优化的细节
- 类型复用:无需自定义
FrameData接口,直接导入motion提供的类型即可,避免类型不一致:import type { FrameData } from "motion/react" - 日志时机:当前
console.log(lenisRef)在useEffect执行时,ReactLenis尚未完成挂载,会打印null。若需调试Lenis实例,建议将日志移到update回调内。 - 取消订阅的简洁写法:
frame.update会返回一个取消函数,直接用它替代cancelFrame更直观:const unsubscribe = frame.update(update, true) return () => unsubscribe()
优化后的代码示例
import { useEffect, useRef } from 'react' import { LenisRef, ReactLenis } from 'lenis/react' import { cancelFrame, frame, type FrameData } from "motion/react" import Preloader from './components/Preloader' function App() { const lenisRef = useRef<LenisRef | null>(null); useEffect(() => { function update(data: FrameData) { lenisRef.current?.lenis?.raf(data.timestamp) // 调试用:查看Lenis实例 // console.log(lenisRef.current?.lenis) } const unsubscribe = frame.update(update, true) return () => unsubscribe() }, []) return ( <ReactLenis options={{ autoRaf: false }} ref={lenisRef}> <Preloader /> </ReactLenis> ) } export default App
内容的提问来源于stack exchange,提问作者David Ajibade
相关产品推荐
相关产品推荐

