Anson LowZF Blog

moon indicating dark mode
sun indicating light mode

How To Create React Parallax Effect With React Hooks

June 24, 2020 #React.js

I want to 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.js?

As a front-end developer who not yet think 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 StackOverflow. Most of the solution is either in Class component or React Refs code.

I started to learn React.js 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.


Covert to React

I want to apply the Parallex JavaScript in React Hero component. How should I do it?

Convert HTML mark up to JSX

<div className="App">
<section className="hero">
<img
src="https://i.picsum.photos/id/10/1080/960.jpg"
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://i.picsum.photos/id/10/1080/960.jpg"
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://i.picsum.photos/id/10/1080/960.jpg"
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>
);
}

What a lousy React fundamental I have. I’m sad!


Final Try Before Asking 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. 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://i.picsum.photos/id/10/1080/960.jpg"
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? I am a real React noob.


Asking For Help

I need to trouble my big brother again, Malcolm Kee. He is a React.js expert and a fanatic. He always guides and helps React beginner in my country - Malaysia. He organizes React KL’s meetup to gather React developers and share tips and tricks and latest information about React.js to the Kuala Lumpur React.js 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://i.picsum.photos/id/10/1080/960.jpg"
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 think he solves it in 30 sec. After seeing his code, I feel like I don’t understand React at all.

I need to strengthen my React.js fundamental. Thank you, Malcolm, I understand React a little bit more today.

Check the Parallax effect in CodeSandbox

Thank you for reading~


A self-taught developer documenting and sharing his learning experience.
React.js • Gatsby.js • Next.js soon. More about me