How To Create React Parallax Effect With React Hooks
Tags: react
Published: 2020-06-24 09:10:02

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

```js
// 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](https://www.npmjs.com/package/react-parallax)
2. [React Spring](https://www.react-spring.io/)
3. [Framer Motion ](https://www.framer.com/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:-

```js
<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:-

```js
<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:-

```js
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!

```js
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](https://twitter.com/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](https://www.kl-react.com/) 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:-

```js
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](https://codesandbox.io/s/parallax-effect-with-react-hooks-2k5hq?file=/src/App.js)

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

{% twitter 1275712317901230080 %}