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
 
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

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