This is a general question about how to best produce parallax effects in React!
I want to directly update the position of an element based on the scroll position. The goal is to have the element appear fixed. I've tried some different methods but always having issues with choppy/flickering behavior in Safari on Mac, sometimes Chrome, and on some devices.
I've tried making the body fixed and have the root div scroll (to get rid of the elastic effect some browsers) but same issues. I've also tried adding translateZ(0) to active 3d rendering but also same issues.
Is this caused by some mechanics in how often React updates the component or is this a browser issue?
Is there a better way to create this effect?
import React, { useState, useEffect } from "react";
const useScroll = () => {
const [scroll, setScroll] = useState(0);
useEffect(() => {
window.addEventListener("scroll", scrollHandler);
return () => {
window.removeEventListener("scroll", scrollHandler);
};
}, []);
const scrollHandler = () => {
setScroll(window.scrollY);
};
return scroll;
};
export default function App() {
const scrollPos = useScroll();
return (
<main style={{ height: "300vh" }}>
<div>Normal Div</div>
<div style={{ transform: `translateY(${scrollPos}px)` }}>Fixed Div</div>
</main>
);
}
This is a simple reproduction of the problem. It produces the same issue for me (choppy in some browsers, esp. Safari on Mac).