To handle the onScroll
event on a React element, assign a function to the onScroll
prop of the element and use the event object to perform an action. That action will occur whenever the user scrolls up or down on the page.
For example:
App.jsx
import { useState } from 'react';
export default function App() {
const [scrollTop, setScrollTop] = useState(0);
const handleScroll = (event) => {
setScrollTop(event.currentTarget.scrollTop);
};
return (
<div>
Scroll top: <b>{scrollTop}</b>
<br />
<br />
<div
style={{
border: '1px solid black',
width: '400px',
height: '200px',
overflow: 'auto',
}}
onScroll={handleScroll}
>
{[...Array(10)].map((_, i) => (
<p key={i}>Content</p>
))}
</div>
</div>
);
}
The function (event listener) passed to the onScroll
prop is invoked whenever the viewport is scrolled. It is called with an event object, which you can use to perform actions and access information related to the scroll event.
The currentTarget
property of this event object returns the element that the onScroll
listener was attached to.
Tip: If you’re not sure of when to use the event object’s currentTarget
or target
properties, this article might help: Event target vs currentTarget in JavaScript: The Important Difference.
We use the element’s scrollTop
property to get how far the element’s scrollbar is from its topmost position. Then we update the state variable with the new value, and this reflects on the page.
Note: We used the useState
hook to manage the state. This hook returns an array of two values, where the first is a variable that stores the state, and the second is a function that updates the state when it is called.
Handle onScroll event on window
object in React
We can also handle the onScroll
event on the global window
object, to perform an action when the viewport is scrolled. We can do this with the addEventListener()
method:
App.js
import { useState, useEffect } from 'react';
export default function App() {
const [scrollTop, setScrollTop] = useState(0);
useEffect(() => {
const handleScroll = (event) => {
setScrollTop(window.scrollY);
};
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, []);
return (
<div>
<div
style={{
position: 'fixed',
padding: '10px 0',
top: '0',
backgroundColor: 'white',
borderBottom: '1px solid #c0c0c0',
width: '100%',
}}
>
Scroll top: <b>{scrollTop}</b>
</div>
<div style={{ marginTop: '50px' }}>
{[...Array(30)].map((_, i) => (
<p key={i}>Content</p>
))}
</div>
</div>
);
}
The addEventListener()
method takes up to two arguments:
type
: a string representing the event type to listen for.listener
: the function called when the event fires.
It also takes some optional arguments, which you can learn more about here.
We call addEventListener()
in the useEffect
hook to register the listener once the component renders as the page loads. We pass an empty dependencies array to useEffect
so this registration happens only once. In the cleanup function, we call the removeEventListener()
method to unregister the event listener and prevent a memory leak.
In the onScroll
listener, we access the Window
scrollY
property to display the number of pixels that the page has currently scrolled horizontally.
Short and clear. Thanks very much.