There are scenarios where you may want elements to move, fade, or animate as the user scrolls. For example, when creating a parallax effect. Implementing this in React requires efficiently tracking the scroll position and updating styles to ensure smooth and seamless animations.

Problem

When you scroll a page, the DOM changes, but React doesn’t automatically know about the scroll position. If you try to directly modify the style in a render function, the component won’t update correctly.

To solve this, you need a reactive, performant way to update the component’s style based on the scroll position.

Solution: React + Hooks + requestAnimationFrame

import React, { useState, useEffect } from "react";
function ParallaxComponent() {
  const [offset, setOffset] = useState(0);
  useEffect(() => {
    let ticking = false;
    const handleScroll = () => {
      if (!ticking) {
        window.requestAnimationFrame(() => {
          setOffset(Math.min(0, window.scrollY / 3 - 60));
          ticking = false;
        });
        ticking = true;
      }
    };
    window.addEventListener("scroll", handleScroll, { passive: true });
   return () => {
      window.removeEventListener("scroll", handleScroll);
    };
  }, []);
  return (
    <div
      style={{
        transform: `translateY(${offset}px)`,
        transition: "transform 0.1s linear",
        height: "300px",
        background: "#90caf9",
        display: "flex",
        justifyContent: "center",
        alignItems: "center",
        fontSize: "24px",
        fontWeight: "bold",
      }}
    >
      Scroll Me
    </div>
  );
}
export default ParallaxComponent;

 

Explanation

  1. useState: Stores the scroll offset so React can re-render the component when it changes.
  2. useEffect: Adds a scroll listener when the component mounts and cleans it up on unmount.
  3. requestAnimationFrame: Ensures updates are smooth and don’t overwhelm the browser.
  4. Inline Styles with Transform: Moves the element vertically according to the scroll position.
  5. Passive Event Listener: { passive: true } improves scroll performance.

Key Takeaways

  • React needs state to detect changes and re-render.
  • Always clean up event listeners in useEffect to avoid memory leaks.
  • Using requestAnimationFrame ensures smooth animations.
  • Inline transforms with transition provide a visually appealing effect.

Need Help With React Development?

Work with our skilled React developers to accelerate your project and boost its performance.

Hire Reactjs Developers

Support On Demand!

Related Q&A