reactjs 成帧器运动未更新scrollYProgress

vc9ivgsu  于 2023-03-12  发布在  React
关注(0)|答案(2)|浏览(85)

我正在使用Framer Motion的useViewportScroll钩子跟踪用户在页面上的滚动,但它没有更新。我偶然发现了this文章,它解释了Framer Motion如何使用document.body.clientHeightwindow.innerHeight来计算视口滚动。
本文解释了一些CSS如何打破这一点,特别是document.body.clientHeight - window.innerHeight <= 0
我似乎不明白为什么这不是真的。即使在我的react应用程序中没有CSS,这个表达式的计算结果也是真的。你可以在this example on CodeSandbox中看到它。
谢谢!

u7up0aaq

u7up0aaq1#

我认为你没有看到更新的原因不是因为任何css。
Framer似乎是从react计算它的状态standalone。所以当Framer在内部更新它的值时。react不一定会用更新的值触发重新渲染。(可能这样做是为了性能)。
您可以通过订阅Framer公开的onChange处理程序来挂钩状态更改,并设置您感兴趣的状态。
例如,scrollYProgress上的onChange将调用setState,从而触发react以重新渲染。

import React from "react";
import { useViewportScroll } from "framer-motion"

const FramerPostionHook = () => {
  const { scrollYProgress } = useViewportScroll();
  const [hookedYPostion, setHookedYPosition] = React.useState(0);
  React.useEffect(()=>{
    // hook into the onChange, store the current value as state.
    scrollYProgress.onChange(v=> setHookedYPosition(v));
  },[scrollYProgress]); //make sure to re-subscriobe when scrollYProgress changes

  return  (<>
  scrollYProgress.current: {scrollYProgress.current}<br/>
  scrollYProgress.hookedYPostion: {hookedYPostion}<br/>
  </>)
}

Sandbox example

s4n0splo

s4n0splo2#

请注意,现在onChange()已被弃用并替换为useMotionValueEvent()
下面使用useMotionValueEvent()更新了Lars的答案

import React from "react";
import { useMotionValueEvent, useScroll } from "framer-motion"

const FramerPostionHook = () => {
  const ref = React.useRef(null);
  const { scrollYProgress } = useScroll({
    target: ref,
    offset: ["start end", "end end"],
  });
  const [hookedYPostion, setHookedYPosition] = React.useState(0);
  useMotionValueEvent(scrollYProgress, "change", (latest) => {
    setHookedYPosition(latest);
  })

  return  (<>
  scrollYProgress.current: {scrollYProgress.current}<br/>
  scrollYProgress.hookedYPostion: {hookedYPostion}<br/>
  </>)
}

相关问题