Open eeshankeni opened 11 months ago
Same issue here. Setting layoutEffect
to false
didn't fix the problem.
I've added extra logs and scrollYProgress
does not change at all during a scroll.
framer: 10.16 next: 13.5.6 (+css modules).
const { scrollXProgress } = useScroll({
layoutEffect: false, <-- This line fixed the problem
container: projectsContainerRef,
});
const { scrollXProgress } = useScroll({ layoutEffect: false,
<-- This line fixed the problem
container: projectsContainerRef, });
Yeah, this fixes the problem, but why does this problem only happen in prod? This is because of SSR or SSG? I don't think so because I had the same problem and I was making use of the 'use client' directive in the entire page. Is the page layout rendered differently in dev? Why? This should happen? Why there isn't anything in the framer motion docs warning about it? I searched in the useScroll section in the docs and there isn't anything warning that this can happen, or detailing what this property does maybe I'm missing something but why the f* there isn't a search bar in the docs?
const { scrollXProgress } = useScroll({ layoutEffect: false,
<-- This line fixed the problem
container: projectsContainerRef, });
this needs to be added in child component, if not clean from answer
const { scrollXProgress } = useScroll({ layoutEffect: false,
<-- This line fixed the problem
container: projectsContainerRef, });Yeah, this fixes the problem, but why does this problem only happen in prod? This is because of SSR or SSG? I don't think so because I had the same problem and I was making use of the 'use client' directive in the entire page. Is the page layout rendered differently in dev? Why? This should happen? Why there isn't anything in the framer motion docs warning about it? I searched in the useScroll section in the docs and there isn't anything warning that this can happen, or detailing what this property does maybe I'm missing something but why the f* there isn't a search bar in the docs?
It only happens in prod because strict mode isn't enabled. Strict mode runs the render function twice to ensure your components are "pure" functions (ie come out with the same results twice). In the first render cycle, the container ref is undefined
hence why useScroll
doesn't work. The second render cycle properly registers useScroll
with the element.
From what I understand useLayoutEffect
runs its logic before any painting, so during the first render the ref will be undefined (because the DOM doesn't exist). Because prod doesn't have the second ref cycle your useScroll
hook is still registered to an undefined container by the time you're coming to use it in something like a useMotionValueEvent
. Setting the layoutEffect
option to false presumably make the hook use a regular effect and therefore will re-render properly with the ref value.
There should definitiely be something in the docs about this options. However, people should also understand the tools they're using a bit better.
UseScroll has a Container prop which is used to keep track of the scroll of a custom container instead of the default scrollable body. Doing so requires a ref to be passed which references the scrollable container. However, if the ref is passed down a component and then the ref is further passed along the component tree then useScroll seems to fail.
https://www.framer.com/motion/use-scroll/
https://github.com/eeshankeni/famer-motion-scroll-bug Now in this case useScroll seems to fail when the ref is passed to a component which is inside of another component (2 levels down).
However, I've noticed that this bug also was happening in a client project when the ref was being passed only 1 component down. I have included this case as well (GreenChildComponent.tsx) in the example but that does not seem to be reproducing.
Steps to reproduce:
yarn install
yarn dev
to run development mode. everything works as expected here.yarn build
to build static files.npx serve@latest out
to run the static page. Notice how the animation breaks here.video demo:
https://github.com/framer/motion/assets/19875557/17c409a7-cc95-4bc3-bb79-e208339fb83a
Edit : Setting
layoutEffect:false
seems to be a workaround. As documented on https://github.com/framer/motion/issues/2452Couldn't find any documentation on what layoutEffect does. Was able to get it figured out.