You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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移除回调,避免组件卸载后内存泄漏。

可优化的细节

  1. 类型复用:无需自定义FrameData接口,直接导入motion提供的类型即可,避免类型不一致:
    import type { FrameData } from "motion/react"
    
  2. 日志时机:当前console.log(lenisRef)在useEffect执行时,ReactLenis尚未完成挂载,会打印null。若需调试Lenis实例,建议将日志移到update回调内。
  3. 取消订阅的简洁写法: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 00:03:24