DEV Community

Cover image for How To Create React Parallax Effect With React Hooks
Anson Low Z.F
Anson Low Z.F

Posted on • Originally published at ansonlowzf.com

How To Create React Parallax Effect With React Hooks

This is my first post in Dev. Thank you for reading~

I want to create a hero section with parallax scrolling effect, the text and image move at a different speed without using any library.

It’s easy to do with vanilla JavaScript:-

// Target parallax container and slow down image's Yoffset for 50%
window.addEventListener("scroll", function () {
  const parallax = document.querySelector(".parallax")
  let scrollPosition = window.pageYOffset

  parallax.style.transform = `translateY(${scrollPosition * 0.5}px)`
})

What if I want to implement the same code in React? I'm stuck for quite some time.

I googled around, most of the guides, tutorials and articles are using:-

  1. React-parallax
  2. React Spring
  3. Framer Motion

When I try to a find solution in Stack Overflow. Most of the solution is either in Class component or React Refs code.

I started to learn React around mid of the year 2019. It’s the React Hooks era. I skipped learning Class component. Hence, I not sure how to resolve Class component and convert it to a functional component with React Hooks.


Create Parallax React Component

I want to write the Parallax JavaScript code in React Hero component. How to do it?

Convert HTML mark up to JSX:-

<div className="App">
  <section className="hero">
    <img
      src="https://picsum.photos/800/600"
      alt="test"
      className="parallax"
    />
    <div className="text-wrapper">
      <h1 className="headline">Parallax</h1>
      <h2 className="sub-headline">Scrolling effect</h2>
    </div>
  </section>
</div>

My First Try

I thought I can just wrap the JavaScript code with parentheses, like how we execute JavaScript code in JSX:-

<div className="App">
  <section className="hero">
    <img
      src="https://picsum.photos/800/600"
      alt="test"
      className="parallax"
    />
    <div className="text-wrapper">
      <h1 className="headline">Parallax</h1>
      <h2 className="sub-headline">Scrolling effect</h2>
    </div>
  </section>
  <!-- Make space to scroll -->
  <section className="overflow"></section>
</div>

{window.addEventListener("scroll", function () {
  const parallax = document.querySelector(".parallax")
  let scrollPosition = window.pageYOffset

  parallax.style.transform = `translateY(${scrollPosition * 0.5}px)`
})}

Of course, it's failed! What a genius!


Second Try

I continue my research and read more article. Oh, I see, if I want to addEventListener, I should write the parallax code in useEffect Hooks.

Without thinking further, I insert the parallax code in:-

export default function App() {

  useEffect(() => {
    window.addEventListener("scroll", function () {
  const parallax = document.querySelector(".parallax")
  let scrollPosition = window.pageYOffset

  parallax.style.transform = `translateY(${scrollPosition * 0.5}px)`
  }, []);

  return (
    <div className="App">
      <section className="hero">
        <img
          src="https://picsum.photos/800/600"
          alt="test"
          className="parallax"
          style={{
            transform: `translateY(${offset * 0.5}px)`
          }}
        />
        <div className="text-wrapper">
          <h1 className="headline">Parallax</h1>
          <h2 className="sub-headline">Scrolling effect</h2>
        </div>
      </section>
    </div>
  );
}

I have lousy React fundamental. I'm sad!


Final Try Before Asking For Help

More googling with different keywords,

  • React parallax effect
  • parallax scroll
  • parallax with React Hooks
  • scrolling in React
  • React onScroll event
  • More

Continue reading more articles. This time, I feel like more pro in React now. Yes, I can do it! Just do it! Come on!

export default function MyApp() {
  const [offset, setOffset] = useState(0)

  useEffect(() => {
    window.onscroll = () => {
      setOffset(window.pageYOffset)
    }
  }, [])

  return (
    <div className="App">
      <section className="hero">
        <img
          src="https://picsum.photos/800/600"
          alt="test"
          className="parallax"
          style={{
            transform: `translateY(${offset * 0.5}px)`,
          }}
        />
        <div className="text-wrapper">
          <h1 className="headline">Parallax</h1>
          <h2 className="sub-headline">Scrolling effect</h2>
        </div>
      </section>
    </div>
  )
}

En~ then what? Where should I write the parallax code? Oh my god, I'm despair.


Asking For Help

I need to trouble my big brother again, Malcolm Kee. He is a React expert and a fanatic. He always guides and helps React beginner in my country - Malaysia. He organises React KL's meetup to gather React developers and share tips and tricks and latest information about React to the Kuala Lumpur React's community.

I reach him out with Twitter and send my code to him though CodeSandbox.

He replies me the following with code:-

import * as React from "react"
import { useEffect, useState } from "react"
import "./styles.css"

export default function App() {
  const [offset, setOffset] = useState(0)

  useEffect(() => {
    function handleScroll() {
      setOffset(window.pageYOffset)
    }

    window.addEventListener("scroll", handleScroll)

    return () => {
      window.removeEventListener("scroll", handleScroll)
    }
  }, [])

  return (
    <div className="App">
      <section className="hero">
        <img
          src="https://picsum.photos/800/600"
          alt="test"
          className="parallax"
          style={{
            transform: `translateY(${offset * 0.5}px)`,
          }}
        />
        <div className="text-wrapper">
          <h1 className="headline">Parallax</h1>
          <h2 className="sub-headline">Scrolling effect</h2>
        </div>
      </section>
    </div>
  )
}

Oh man, I can understand the code. All my learning are like went into the deep sea. I cannot recall when I want to use it. Then I have the a-ha moment when see people write the code.

I think Malcolm solves it in 1 min, but I struggle for many hours.
I need to strengthen my React fundamental. Thank you, Malcolm, I understand React a little bit more today.

Check the Parallax effect in CodeSandbox

Thank you for reading~ If you don't mind to make friend with a React Noobie. Reach me out @ Twitter

Top comments (3)

Collapse
 
khimaira profile image
Khimaira • Edited

Nice journey experience! thx for sharing! have not play with Parallax. is in my todo list!. Check react-spring.io/components/parallax

Collapse
 
aishtiaq7 profile image
Awshaf Ishtiaque

What is the best lib to incorporate Parallax Scrolling effect?

Collapse
 
ansonlowzf profile image
Anson Low Z.F

I haven't find one I like yet. I use the code in this article at the moment